当讨论Scala时,类型系统总是被提到作为主要特征之一。它被称为强大的,并且是语言名字对象的主要原因(Scala是“可伸缩语言”的缩写)。有人可以解释Scala键入的工作方式/为什么这个独特的,以及它如何有助于语言的可扩展性?
答案 0 :(得分:46)
我不认为现有的答案是恰当的。 Scala有很多便利,但它们与类型系统无关,因为它们与类型有关。事实上,类型推断与类型系统的力量直接冲突 - 如果它不那么强大,可以有完整的类型推断(如在Haskell中)。
所以,
接下来,有一些与Scala隐含相关的功能,这是上面所包含的功能。
与上一条评论相关,implicits和类型推断一起使Scala的类型系统 turing complete 。也就是说,您将任意程序编码为类型,编译器将在编译时“运行”。证明here,通过SKI微积分,在类型中带有“错误”无限循环作为进一步的演示。
上面的功能列表相当大,令人印象深刻。然而,Scala结合implicits和类型推断的方式在编译时生成静态证明(例如视图边界和上下文边界),这使得Scala的类型系统是唯一的。 AFAIK,没有其他语言可以做到这一点,尽管肯定有其他语言通过其他方式提供证明功能。
答案 1 :(得分:20)
Scala的类型系统优于Java的一些优点:
在许多情况下可以推断出类型,而不是明确指定。这更方便,但它促进了使用复杂的类型。
val map = new Map[String, (String, String)]()
而不是
Map<String, Tuple<String, String>> map = new HashMap<String, Tuple<String, String>>()
可以在类型系统中简单表达函数。如果你想看看它有多强大,可以考虑将番石榴库作为Java的解决方案。它令人难以置信的约束和冗长(但仍然有用)。
val double = (x: Int) => x * 2
而不是(使用番石榴)
Function<Integer, Integer> double = new Function<Integer, Integer>() { @Override public Integer apply(Integer value) { return value * 2; }}
元组是Scala中的一种类型,它绕过了Java只能返回单个值的问题。
Scala支持类型Variances,因此当Cat是Thing的子类型时(或反向关系成立时),您可以指定SomeObject是SomeObject的子类型。在java中,generics are not covariant,这通常是有问题的。
Scala使用traits支持有限形式的多重继承。与接口(其中多个可以用Java实现)不同,traits可以定义方法和变量。
数组与任何其他类一样透明地处理。
您可以通过隐式定义添加methods to existing classes。例如,您可以向Arrays of Integers添加“sum”方法。
class IntArray(value: Array[Int]) { def sumIt = value.reduceRight(_+_) }
implicit def pimpArray(xs: Array[Int]) = new IntArray(xs)
Array(1,2,3).sumIt
这是上述某些主题的另一个好资源:http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-5
答案 2 :(得分:6)
除了schmmd的优秀答案外,Scala的类型系统还有更重要的功能:
object
是Java中static
成员变量和方法的干净替代品,例如object
有自己的类型,可以作为参数传递type
声明:您可以为复杂类型定义别名,例如type FactorMap[A] = Map[A, Set[Int]]
最后一点是我的最爱之一。例如。你不能用Java编写一个简单的通用仿函数接口。你需要 ......
public interface Function<A,B> {
public B apply(A a);
}
//not valid Java
public interface Functor<C> {
public <A,B> C<B> map(Function<A,B> fn, C<A> ca);
}
如果您替换某些具体类型(例如List
而不是C
),则此方法有效。在Java中,您可以抽象出一个包含的内容(例如,通过编写`List),但是您不能在容器本身上抽象。相信我,我试图找到漏洞(结果是this)。在Scala中,这是一件轻而易举的事:
trait Functor[C[_]] {
def map[A,B](fn: A => B, ca: C[A]):C[B]
}
object ListFunctor extends Functor[List] {
def map[A,B](fn: A => B, ca: List[A]):List[B] = ca.map(fn)
}
答案 3 :(得分:3)
任何类型的系统,你可以编码HList,TList和HOF的类型是相当强大的恕我直言。有关详细信息,请参阅http://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/。
答案 4 :(得分:0)
我不知道你是否了解Java,但想象Scala的类型系统是这样的:
我会更喜欢o wrie,我的键盘jus坏了,对不起!