gpt4 book ai didi

scala - 为什么案例模式匹配匿名函数可以有两个签名,并且具有神奇的调用站点兼容性

转载 作者:行者123 更新时间:2023-12-05 08:25:34 29 4
gpt4 key购买 nike

在 Scala 中,模式匹配匿名函数一直让我感到惊讶。我刚刚发现了以下行为,我想知道如何理解它。

看来,匿名函数{ case (a, b) => (b, a) } 的参数签名既可以注解为单个元组参数,也可以注解为参数元组:

scala> ({ case (a, b) => (b, a) }: ((Int, Int)) => (Int, Int))
val res1: ((Int, Int)) => (Int, Int) = $Lambda$1160/0x0000000801127040@689fe2a3

scala> ({ case (a, b) => (b, a) }: (Int, Int) => (Int, Int))
val res2: (Int, Int) => (Int, Int) = $Lambda$1161/0x000000080106e840@1784d711

注意 res1 有一个元组参数,而 res2 有两个参数。这是为什么?这种行为是否在语言规范中定义? (对不起,还没有退房,目前对我来说似乎太密集了。)

此外,res1 函数神奇地接受了一个元组参数和两个调用点参数。

scala> res1((1,2))
val res3: (Int, Int) = (2,1)

scala> res1(1,2)
val res4: (Int, Int) = (2,1)

相比之下,res2 不接受元组参数:

scala> res2((1,2))
^
error: not enough arguments for method apply: (v1: Int, v2: Int): (Int, Int) in trait Function2.
Unspecified value parameter v2.

这是怎么回事?为什么 res1 可以根据需要更改其签名?

最佳答案

Is this behaviour defined in language specs?

根据open issue好像没有说明Spec doesn't mention automatic tupling #3583

What's going on here? Why res1 can change its signature as it sees fit?

此功能称为自动双倍化。正如 Remove Two Warts: Auto-Tupling and Multi-Parameter Infix Operations #4311 中所讨论的那样,它可能会使某些调用站点更加自然。

(x, y) == z
z == ((x, y)) // !yuck

许多人主张删除/限制它,例如,Let’s drop auto-tupling .

编译器标志 -Xlint:adapted-args可以在自动元组发生时发出警告,例如

➜  ~ scala
Welcome to Scala 2.13.3 (OpenJDK 64-Bit Server VM, Java 1.8.0_265).
Type in expressions for evaluation. Or try :help.

scala> def foo (x: (Int, Int)) = x
def foo(x: (Int, Int)): (Int, Int)

scala> foo (1,2)
val res0: (Int, Int) = (1,2)

scala> :replay -Xlint:adapted-args
replay> def foo (x: (Int, Int)) = x
def foo(x: (Int, Int)): (Int, Int)

replay> foo (1,2)
foo (1,2)
^
On line 2: warning: adapted the argument list to the expected 2-tuple: add additional parens instead
signature: foo(x: (Int, Int)): (Int, Int)
given arguments: 1, 2
after adaptation: foo((1, 2): (Int, Int))
def foo(x: (Int, Int)): (Int, Int)
val res0: (Int, Int) = (1,2)

另一个相关标志是-Xlint:multiarg-infix , 例如

➜  ~ scala
Welcome to Scala 2.13.3 (OpenJDK 64-Bit Server VM, Java 1.8.0_265).
Type in expressions for evaluation. Or try :help.

scala> def % (a: Int, b: Int) = (a,b)
def $percent(a: Int, b: Int): (Int, Int)

scala> :replay -Xlint:multiarg-infix
replay> def % (a: Int, b: Int) = (a,b)
^
warning: multiarg infix syntax looks like a tuple and will be deprecated
def $percent(a: Int, b: Int): (Int, Int)

关于scala - 为什么案例模式匹配匿名函数可以有两个签名,并且具有神奇的调用站点兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63859326/

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