Is there a good way to use `try/catch` in init blo...
# announcements
n
Is there a good way to use
try/catch
in init blocks to initialize immutable (i.e.
val
) class properties? Right now I use
Copy code
class Foo(val a: Int) {
val b: Int
init {
  var bb: Int
  try {
    bb = complicated(a)
  catch (e: Excepetion) {
    bb = fallback()
  }
  b = bb!!
}
c
Copy code
class Foo(val a: Int) {
  val b: Int
  init {
    b = try {
      complicated(a)
    } catch (e: Exception) {
    fallback()
  }
}
or even
Copy code
class Foo(val a: Int) {
  val b: Int = try {
    complicated(a)
  } catch (e: Exception) {
    fallback()
  }
}
👍 3
👆 1
and if you don't need a outside of initialization, you can
class Foo(a: Int)
n
great. Any idea what to do if I have 2 values to compute from within the same
try
? I tied
val (b, c) = try {...}
but that produces a syntax error.
val p = try {...}; val b = p.first; val c = p.second
works but looks ugly
s
I mean, there’s a couple things you could do here
if you wrote the type that
p
is, you can define
.component1()
and
.component2()
such that they return first and second, respectively
then you can use the destructuring syntax
if you don’t, you could return a
Pair
from the try/catch though it’s not the most intuitive
Copy code
val (a, b) = try {
    mightThrow()
  } catch (_: Exception) {
    default()
  }
}

fun mightThrow() = 1 to 2
fun default() = 3 to 4
n
I tried that (my
try
did return a
Pair
) but Intellj showed a syntax error for this when I used this approach for class properties. It did work for local values in functions
s
ahh, I see, yes, I don’t think you’re allowed to destructure into properties
n
I ended up with
Copy code
class foo() {
    private fun mightThrow() = 1 to 2
    private fun default() = 3 to 4

    val a: Int
    val b: Int

    init {
        val p = try {
            mightThrow()
        } catch (_: Exception) {
            default()
        }
        a = p.first
        b = p.second
    }
}