Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scala中的类型参数_Scala - Fatal编程技术网

scala中的类型参数

scala中的类型参数,scala,Scala,我试图理解scala中的类型参数概念 def sum [A] (a:A):A={a} // used single parameter and its working fine, able to pass any data type. 在这里: 上面的函数有一个类型参数,我没有提到任何数据类型——那么它怎么会被视为字符串呢 def sum[A](a:A,b:A):A={a+b} 您正在添加T+T,编译器无法推断T的+值,它将使用默认的隐式+:any2stringad,因此编译器将抛出requ

我试图理解scala中的类型参数概念

def sum [A] (a:A):A={a}
// used single parameter and its working fine, able to pass any data type.
在这里:

上面的函数有一个类型参数,我没有提到任何数据类型——那么它怎么会被视为字符串呢

def sum[A](a:A,b:A):A={a+b}
您正在添加T+T,编译器无法推断T的+值,它将使用默认的隐式+:any2stringad,因此编译器将抛出required:String错误


让我们从一个稍微不同的角度来看这个问题:实际上,什么是参数?这是什么意思

让我们从您可能更熟悉的东西开始:值参数。子程序中的值参数是什么意思?比如说,我们有这样的东西:

def foo(a, b) = { /* … */ } // deliberately ignoring types and the body
这意味着:我有一个子例程foo,它有两个参数,a和b。子例程是通用的,它不关心a和b的实际具体值是什么。它适用于a和b的所有值,因为它甚至不知道a和b的值是什么

更具体一点:

def plus(a: Int, b: Int) = a + b
再说一次,plus不知道a和b的实际值是多少。它适用于2和3,也适用于23和42或0和0。它完全不知道a和b的具体值。它只知道a和b的存在

现在,类型参数是一样的,只是在类型级别而不是值级别

blabla[A]
在类型级别上的意思与blablaa在值级别上的意思相同:我有一个东西,我不知道它是什么,我也不在乎,但我称它为a

所以,实际上,您所做的是告诉Scala您对A一无所知,但随后您对它做了一些事情,或者更确切地说,对它的实例做了一些事情:添加它。但是,你怎么知道你可以添加它呢?你甚至不知道那是什么

因此,添加它不可能工作,它必须失败

然而,它失败的方式有点奇怪,并且与对象中的一些预定义属性有关。特别是。在本例中,它将a转换为an,然后尝试向其中添加b,但该方法仅将字符串作为其参数,因此您会收到奇怪的错误消息,即它需要一个字符串

[请注意,any2stringadd是,因此将来您只会得到一个关于不存在的方法的错误。]

当您有复杂的类型错误时,有时会弹出一些其他类似的类型:

,:这些类型位于Scala类型层次结构的最顶端。有时,当您遇到一些编程错误时,您认为您正在从两个不同的代码路径返回相同的类型,但实际上您返回了两个不同的类型,Scala仍会尝试推断这两个类型之间的公共类型,最终导致唯一的公共祖先是Any、AnyRef或AnyVal。这有点像Java或C中的对象♯. :这实际上和上面的一样。很多完全不同的类型实现了Serializable接口,所以有时候当您有两个非常不同的类型,而您实际上期望相同的类型时,Scala会很有帮助地推断Serializable是最接近的共同祖先,然后因为您使用Serializable做了它不支持的事情而对您大喊大叫。 是所有产品的一个超级特征,即…和所有元组,即。产品也混合到所有案例类别中。因此,如果你有两个不同算术的元组或两个不相关的case类,例如,你有时返回,但意外地返回了一些东西ftypefoo而不是,那么和你的case类Foo之间最精确的公共类型将被推断为乘积或… 可序列化的产品:也可以接收上述产品的组合。例如,元组是可序列化的,因此这实际上是两个不同算术性的元组中最精确的常见类型。 遇到这些问题的一种常见方法是使用条件表达式,而不使用其他表达式:

这是什么类型的退货?不then分支返回Int,而else分支不返回任何内容,因为没有else分支。Scala实际上有一个不返回任何内容的返回类型:。Unit是AnyVal的子类型,Int是AnyVal的子类型,因此条件表达式的两个分支的类型的最接近的共同祖先实际上是AnyVal,而不是Int。注意:else分支不可访问这一事实从类型角度看是不相关的。可达性是运行时的事情,类型是编译时的事情

def plus(a: Int, b: Int) = a + b
blabla[A]
if (true) 42