Как я могу обработать несколько значений в try-catch конструктора - PullRequest
1 голос
/ 10 июня 2019

Я легко могу справиться с ошибочным присваиванием в конструкторе:

val v: BigDecimal

constructor(s: String) {
  v = try {
    BigDecimal(s)
  }
  catch (e: Exception) {
    BigDecimal.ZERO
  }
}

Но как мне справиться со случаем, если мне нужно заполнить две переменные? Это не работает:

constructor(s: String) {
  (v, type) = try {
    Pair(BigDecimal(s), RealTypes.Normal)
  }
  catch (e: Exception) {
    Pair(BigDecimal.ZERO, RealTypes.NaN)
  }
}

Валы могут быть назначены только один раз, конечно, хотя я не уверен, что конструктор не может быть исключением из этого правила. Но на самом деле это тоже не работает из-за этого правила:

constructor(value: String) {
  v = try {
    type = RealTypes.Normal
    BigDecimal(value, context)
  }
  catch (e: Exception) {
    type = RealTypes.NaN
    BigDecimal.ZERO
  }
}

Ответы [ 5 ]

1 голос
/ 10 июня 2019

А как насчет этого?

constructor(s: String) {
    val result = runCatching { BigDecimal(s) }
    v = result.getOrDefault(BigDecimal.ZERO)
    type = if (result.isSuccess) RealTypes.Normal else RealTypes.NaN
}

Или что?

constructor(s: String) {
    runCatching { BigDecimal(s) }.apply {
        v = getOrDefault(BigDecimal.ZERO)
        type = if (isSuccess) RealTypes.Normal else RealTypes.NaN
    }
}
1 голос
/ 10 июня 2019

А как насчет использования локальных переменных, как это?

val bigDecimal: BigDecimal
val bigDecimalType: RealTypes

constructor (s: String) {
    var number: BigDecimal
    var type: TealTypes

    try {
        type = RealTypes.Normal
        number = BigDecimal(s)
    } catch (e: Exception) {
        type = RealTypes.NaN
        number = BigDecimal.ZERO
    }
    bigDecimal = number
    bigDecimalType = type
}

Здесь number и type - локальные переменные конструктора, которые будут присваиваться bigDecimal и bigDecimalType val.

1 голос
/ 10 июня 2019

Ну, я нашел такой подход к работе, но он мне не очень нравится.

constructor(s: String) {
  val (v, type) = try {
    Pair(BigDecimal(value), RealTypes.Normal)
  }
  catch (e: Exception) {
    Pair(BigDecimal.ZERO, RealTypes.NaN)
  }
  this.v = v;
  this.type = type;
}
0 голосов
/ 10 июня 2019

Вы можете использовать флаг, чтобы узнать, было ли выброшено исключение:

class Foo {
    val a: BigDecimal
    val b: RealTypes

    constructor(s: String) {
      var failed = false  

      a = try { 
          BigDecimal(s)
      } catch (e: NumberFormatException) { 
          failed = true
          BigDecimal.ONE
      }

      b = if(failed) RealTypes.NaN else RealTypes.Normal  
    }
}

Таким образом, вы можете использовать нотацию выражения сначала для исключения, а затем для блока if-else, который защищает ограничение на то, что val может быть инициализирован только один раз.

Примечание. Рекомендуется отлавливать конкретные исключения, если ясно, что это за исключение (в данном случае NumberFormatException).

0 голосов
/ 10 июня 2019

Вместо Val используйте lateinit var в классе конструктора.Это пример

class Myclass() {
lateinit var v: BigDecimal

constructor(s: String) : this() {
    v = try {
        BigDecimal(s)
    } catch (e: Exception) {
        BigDecimal.ZERO
    }
}

fun print() {
    println(v)
}
}

, затем позвоните вот так

  Myclass("100").print()     //output is 100
...