我在Scala中尝试了一些来自Python的东西。由于Scala对于保持类型一致性要严格得多,我很惊讶地发现我可以执行以下串联,这会在Python中爆炸:
def adder(one:Any, two:String) = {one+two}
adder("word", "suffix")
res13:String = wordsuffix
但是:
val x:Int = 1
adder(x, "suffix")
res12:String = 1suffix
所以它只是将Int
转换成String
w / out告诉我。这叫什么,背后的逻辑是什么?
这有什么好处?我觉得它可以回来咬我,例如处理用户对函数的输入时。
我知道这不是很具体,如果这个问题太宽泛,我很乐意撤回这个问题。
答案 0 :(得分:4)
{
...
"bin": {
"mathexample22may": "./bin/main.js"
},
...
}
中有一个隐式类,可以对任何类型的对象进行操作
scala.Predef
实现 implicit final class any2stringadd[A](private val self: A) extends AnyVal {
def +(other: String): String = String.valueOf(self) + other
}
(正如您在Any + String
中定义的那样)。正如流氓提到的那样,还有一种连接adder
defined in StringOps
的方法。如果您尝试String + Any
,它会失败,因为它期望Any + Any
作为参数。
所以它只是将一个Int变换为一个字符串w / out告诉我
Scala正在将您的String
转换为Int
,但这不是类型转换,因为String
无法强制转换为Int
。您可以通过尝试这样的事情来观察:
String
这将无法编译,因为Scala无法将def foo(str: String) = ???
foo(5) // Type mismatch: expected: String, actual: Int
神奇地强制转换为Int
。
背后的逻辑是什么?
这有什么好处?我觉得它可以回来咬我,例如处理函数的用户输入时。
这是一种非常特定于String
和连接的便捷方法。此功能是用Java实现的,所以我相信它是在Scala中实现的,以保持源兼容性。我上面的例子表明(除了在这种特定情况下),函数的用户输入将遵循函数中定义的类型。
答案 1 :(得分:1)
此字符串连接不仅适用于Int,也适用于任何数据类型。例如
scala> case class Elephant(value: String)
defined class Elephant
scala> "Hello" + Elephant("elephant")
res2: String = HelloElephant(elephant)
这是因为StringOps(通过Predef)类中定义的method +
接受类型为Any的参数。因此,它是一个通过隐式转换提供给String对象的方法,该转换采用类型Any
的参数。所以"Hello" + Elephant("elephant")
实际上是"Hello".+(Elephant("elephant"))
答案 2 :(得分:1)
您可以检查scala.Predef
以查看隐式转换类型时使用的所有方法,然后您可以使用scala.language.implicitConversions
来控制它。阅读更多Scala Documentation。