为什么我可以在Scala中连接String和Int?

时间:2017-05-24 00:42:30

标签: scala types

我在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告诉我。这叫什么,背后的逻辑是什么?

  • 这有什么好处?我觉得它可以回来咬我,例如处理用户对函数的输入时。

我知道这不是很具体,如果这个问题太宽泛,我很乐意撤回这个问题。

3 个答案:

答案 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

  

背后的逻辑是什么?

请参阅implicit classes

  

这有什么好处?我觉得它可以回来咬我,例如处理函数的用户输入时。

这是一种非常特定于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