Scala constructor exception exception

What is the Scala equivalent of this Java code, where someMethodThatMightThrowException defined elsewhere?

 class MyClass { String a; String b; MyClass() { try { this.a = someMethodThatMightThrowException(); this.b = someMethodThatMightThrowException(); } finally { System.out.println("Done"); } } } 
+4
source share
4 answers
 class MyClass { private val (a, b) = try { (someMethodThatMightThrowException(), someMethodThatMightThrowException()) } finally { println("Done") } } 

try is an expression in Scala, so you can use its value. Using tuples and pattern matching, you can use the operator to get more than one value.

Alternatively, you can use almost the same code as in Java:

 class MyClass { private var a: String = _ private var b: String = _ try { a = someMethodThatMightThrowException() b = someMethodThatMightThrowException() } finally { println("Done") } } 
+5
source

with associated object

 case class MyClass(a: String, b: String) object MyClass { def apply() = try { new MyClass( a = someMethodThatMightThrowException(), b = someMethodThatMightThrowException() ) } finally { println("Done") } } 

overloading with a constructor is a bit more complicated because we cannot wrap this (...):

 def tryIt[T](something: => T) = try{ something } finally { println("Done") } case class MyClass(a: String, b: String) { def this() = this( tryIt(someMethodThatMightThrowException), tryIt(someMethodThatMightThrowException) ) } 
+1
source

What is a or b if an exception occurs? Wrap a and b in Try to handle exceptional cases. You can also map a pattern for them to extract values.

 scala> class MyClass(val a: Try[String], val b: Try[String]) defined class MyClass scala> new MyClass(Try("foo"(0).toString), Try("foo"(3).toString)) res0: MyClass = MyClass@6bcc9c57 scala> res0.a res1: scala.util.Try[String] = Success(f) scala> res0.b res2: scala.util.Try[String] = Failure(java.lang.StringIndexOutOfBoundsException: String index out of range: 3) scala> res0.a.get res3: String = f scala> res0.b.get java.lang.StringIndexOutOfBoundsException: String index out of range: 3 at java.lang.String.charAt(String.java:658) ... 

Editing comments. Uses argumens for a and b by default .

null bad, but that is what you asked for. See Option

 class MyClass(val a: Try[String] = null, val b: Try[String] = null) scala> new MyClass(Success("a")) res50: MyClass = MyClass@625aaaca scala> res50.a res51: scala.util.Try[String] = Success(a) scala> res50.b res52: scala.util.Try[String] = null scala> new MyClass(b = Success("b")) res53: MyClass = MyClass@68157e85 scala> res53.a res54: scala.util.Try[String] = null scala> res53.b res55: scala.util.Try[String] = Success(b) 
+1
source

How about something closer to:

 scala> def foo = ??? foo: Nothing scala> :pa // Entering paste mode (ctrl-D to finish) case class Foo(a: String = Foo.afoo, b: String = Foo.bfoo) object Foo { import util._ def afoo = Try (foo) recover { case _ => "a" } get def bfoo = Try (foo) recover { case _ => "b" } get } // Exiting paste mode, now interpreting. warning: there were 2 feature warning(s); re-run with -feature for details defined class Foo defined object Foo scala> Foo() res0: Foo = Foo(a,b) 
+1
source

Source: https://habr.com/ru/post/1500356/


All Articles