Why is there a difference in behavior between these two pattern matches in a for comprehension?

后端 未结 2 1636
暗喜
暗喜 2020-12-11 08:01

Consider this Map[String, Any]:

val m1 = Map((\"k1\" -> \"v1\"), (\"k2\" -> 10))

Now let\'s write a for:

相关标签:
2条回答
  • 2020-12-11 08:18

    Well, the latter example doesn't work because it isn't spec'ed to. There's some discussion as to what would be the reasonable behavior. Personally, I'd expect it to work just like you. The thing is that:

    val v: String = (10: Any) // is a compile error
    (10: Any) match {
        case v: String =>
    } // throws an exception
    

    If you are not convinced by this, join the club. :-) Here's a workaround:

    for (va @ (v: String) <- l1) println(v)
    

    Note that in Scala 3, you can:

    for (case v: String <- l1) println(v)
    
    0 讨论(0)
  • 2020-12-11 08:27

    The main reason for the speced behavior is that we want to encourage people to add type annotations, for clarity. If in for comprehensions, they get potentially very costly filter operations instead, that's a trap we want to avoid. However, I agree that we should make it easier to specify that something is a pattern. Probably a single pair of parens should suffice.

    val x: String = y       // type check, can fail at compile time
    val (x: String) = y     // pattern match, can fail at run time
    
    for (x: String <- ys)   // type check, can fail at compile time
    for ((x: String) <- ys) // pattern match, can filter at run time
    
    0 讨论(0)
提交回复
热议问题