gpt4 book ai didi

Scala 括号语义

转载 作者:行者123 更新时间:2023-12-01 08:31:48 25 4
gpt4 key购买 nike

向 MAP 附加值时,为什么 Scala 需要额外的括号块来使此语句起作用?

不编译:

vmap += (item.getName(), item.getString()) // compiler output: "found: String"

但是,这确实编译:
vmap += ((item.getName(), item.getString())) // note the second set of enclosures

TIA

编辑: vmap 定义为
val vmap = new mutable.HashMap[String, String]()

结语:
在进行此编辑时,有一些帖子详细说明了两种可能的解释,这两种解释似乎都包含对他们来说真实的元素。哪一个实际上是正确的?我不能肯定地说......我只是一个仍在学习语言的人。话虽如此,我已经根据一个答案(至少在某种程度上)包含在另一个答案中的感觉更改了答案选择 - 所以我选择了更大的图景,因为我认为它会提供更广泛的含义为其他人寻找答案。具有讽刺意味的是,我试图更好地理解如何消除语言的一些细微差别,而我逐渐意识到这些细微差别比我想象的要多。我并不是说这是一件坏事 - 事实上(IMO)它是任何灵活和复杂的语言都可以预期的 - 但它确实会让一个人不时错过 Assembly 的黑白世界...

为了结束这一点,有几点意见:
1) 所选答案包含一个链接,指向一个充满 Scala 脑筋急转弯的网站(我发现这对于尝试理解该语言中的一些上述夸克非常有帮助。)强烈推荐。
2)我确实遇到了另一个有趣的转折 - 而单括号(上面的例子)不起作用,将其更改为以下并且它工作得很好......
vmap += ("foo" -> "bar")

这可能与匹配方法/函数签名有关,但这只是我的猜测。

最佳答案

接受的答案实际上是错误的。

您没有得到 Map.+= 元组的原因是该方法被第二个方法重载,该方法需要两个或多个参数。

如果 args 的数量错误,编译器只会尝试元组。但是如果你给它两个参数,并且有一个方法需要两个参数,那就是它的选择,即使它没有键入检查。

它不会开始尝试所有可能的组合,直到某些事情奏效,因为那会充满晦涩。 (参见隐式。)

scala> def f(p: Pair[String, Int]) = { val (s,i) = p; s.toInt + i }
f: (p: Pair[String,Int])Int

scala> f("2",3) // ok to tuple
res0: Int = 5

scala> trait F { def +=(p: Pair[String, Int]) = f(p) }
defined trait F

scala> val foo = new F {}
foo: F = $anon$1@6bc77f62

scala> foo += ("2",3) // ok to tuple
res1: Int = 5

scala> trait G { def +=(p: Pair[String, Int]) = f(p); def +=(p:(String,Int),q:(String,Int),r:(String,Int)*) = f(p)+f(q)+(r map f).sum }
defined trait G

scala> val goo = new G {}
goo: G = $anon$1@183aeac3

scala> goo += ("2",3) // sorry
<console>:12: error: type mismatch;
found : String("2")
required: (String, Int)
goo += ("2",3)
^

scala> goo += (("2",3),("4",5),("6",7))
res3: Int = 27

我不会提到你和我的 friend ,-Xlint,它会警告不合适的 arg 改编:
apm@mara:~/tmp$ skala -Xlint
Welcome to Scala version 2.11.0-20130811-132927-95a4d6e987 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def f(p: Pair[String, Int]) = { val (s,i) = p; s.toInt + i }
f: (p: Pair[String,Int])Int

scala> f("2",3)
<console>:9: warning: Adapting argument list by creating a 2-tuple: this may not be what you want.
signature: f(p: Pair[String,Int]): Int
given arguments: "2", 3
after adaptation: f(("2", 3): (String, Int))
f("2",3)
^
res0: Int = 5

scala> List(1).toSet()
<console>:8: warning: Adapting argument list by inserting (): this is unlikely to be what you want.
signature: GenSetLike.apply(elem: A): Boolean
given arguments: <none>
after adaptation: GenSetLike((): Unit)
List(1).toSet()
^
res3: Boolean = false

关于适应的危险,请参阅 the Adaptive Reasoning puzzlerthis new one that is pretty common,因为我们了解到括号的存在与否在很大程度上取决于样式,而当括号真的很重要时,错误地使用它们会导致类型错误。

在存在重载的情况下调整元组:
scala> class Foo {
| def f[A](a: A) = 1 // A can be (Int,Int,Int)
| def f[A](a: A, a2: A) = 2
| }
defined class Foo

scala> val foo = new Foo
foo: Foo = Foo@2645d22d

scala> foo.f(0,0,0)
<console>:10: warning: Adapting argument list by creating a 3-tuple: this may not be what you want.
signature: Foo.f[A](a: A): Int
given arguments: 0, 0, 0
after adaptation: Foo.f((0, 0, 0): (Int, Int, Int))
foo.f(0,0,0)
^
res9: Int = 1

关于Scala 括号语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18238744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com