【发布时间】:2019-12-14 06:20:48
【问题描述】:
我正在学习 Scala,发现如下:
List(('a', 1)).toMap get 'a' // Option[Int] = Some(1)
(List(('a', 1)).toMap) apply 'a' // Int = 1
(List(('a', 1)).toMap)('a') // Error: type mismatch;
found : Char('a')
required: <:<[(Char, Int),(?, ?)
(List(('a', 1)).toMap)('a')
但随后将其分配给变量再次起作用。
val b = (List(('a', 1)).toMap)
b('a') // Int = 1
为什么会这样?
标准文档给出:
ms get k映射 ms 中与键 k 关联的值作为选项,如果未找到则无。
ms(k)(或者,写出来,ms apply k)map ms 中键 k 关联的值,如果没有找到则异常。
为什么第三行不起作用?
【问题讨论】:
-
这里发生了很多事情。首先,您的示例不正确。
get如文档所述,返回一个 Option 而apply返回一个普通值。如果密钥不存在,get将返回 None,而apply将抛出 Exception - 其次,问题在于,toMap收到一些隐含的论点。这就是为什么最好将代码分成两行的原因,因为它会使您的apply与传递这些参数混淆。 -
@LuisMiguelMejíaSuárez 已更正示例,感谢您指出这一点。你能解释一下“隐含的论点”吗?
-
@LieuZhengHong 这是一个很好的问题,而且这种行为确实是违反直觉的。 this duplicate 会回答你的问题吗?本质上,它试图将
'a'视为toMap的隐含参数。这在这里有效:(List((1, 2)).toMap(implicitly[(Int, Int) <:< (Int, Int)]))(1)。这也有效:List((1, 2)).toMap.apply(1)。但由于有问题的原因,仅使用括号是行不通的。
标签: scala implicit syntactic-sugar