我在Scala中创建一个简单的函数
def addOne(m: Int): Int = m + 1
将它与整数一起使用可以正常工作,使用double会抛出类型不匹配错误。
addOne(2) = 3
addOne(2.1) = error: type mismatch
当我使用双引号中的字符时,它会按预期抛出类型不匹配。
addOne("z") = error: type mismatch
但是,当使用单引号字符时,它会返回该字母的值。
addOne('z') = 123
这里发生了什么,为什么会这样?
答案 0 :(得分:3)
您可以使用Char
作为参与Int
的函数的原因是因为Scala执行从Char
到Int
的隐式转换。此特定转换在Char
类的伴随对象中定义。见这里:
http://www.scala-lang.org/api/2.12.1/scala/Char $。html(似乎SO在$字符处打破此链接。请将其复制粘贴)
执行转换的功能称为char2int
。它将Char
转换为相应的Unicode值Int
。
当Scala编译器发现类型Char
和Int
不匹配时,它将首先检查是否存在任何可用的隐式转换。如果找不到,它只会产生编译错误。如果它找到隐式转换,它会将该函数调用插入到您的代码中。因此,您的代码将转换为:
addOne(Char.char2int('z'))
如果您想进行自己的隐式转换,例如,让您的函数接受String
,您可以定义:
// Enable implicit conversions.
import scala.language.implicitConversions
// The "implicit" modifier is the important part here, not the name of the function.
implicit def string2int(s: String) = s.toInt
现在编译:
// This returns 6
addOne("5")
/*
* This throws a NumberFormatException due to my implementation of string2int.
* Create your own implementation of string2int if you want it to work properly.
*/
addOne("a")
最后:请注意,隐式转换非常强大,因此可能很危险!请参阅TheArchetypalPaul的评论以获得解释。
答案 1 :(得分:-1)
这是因为addOne(m: Int)
[冒号(:)之后的部分告诉Scala你会将Int传递给它,而不是Double,而不是其他任何东西。
如果你想让它适用于Double,试试这个,但是你总会得到Double as Result。
def addone (m : Double ) = m+1
addone: (m: Double)Double
scala> addone(1)
res0: Double = 2.0
scala> addone(1.1)
res1: Double = 2.1
答案 2 :(得分:-1)
Scala使用ASCII Table映射char类型。因此,'z'
映射到122,这是一个整数。在方法addOne('z')
中,输入参数被强制转换为整数(即122)。
但是,addOne(2.1)
中的输入参数是2.1,这是一个双精度,而addOne("z")
中的输入参数是一个字符串。它们不能自动转换为整数。
答案 3 :(得分:-1)
def addOne(m: Int): Int = m + 1
仅接受m
的整数
它也适用于单引号字符(z
),因为它被转换为ASCII值。 'z'的值为122,您加1。
阶> val foo:Int ='z'
foo:Int = 122
阶> val bar = foo + 1
bar:Int = 123
如果您想使用double工作,可以指定def addOne(m: Double): Double = m + 1