我刚刚开始研究即将发布的2.8版本中的Scala集合库重新实现.熟悉2.7中的库的人会注意到,从使用角度来看,库几乎没有变化.例如...
> List("Paris", "London").map(_.length)
res0: List[Int] List(5, 6)
Run Code Online (Sandbox Code Playgroud)
......适用于任何一个版本.图书馆非常实用:实际上它太棒了.然而,那些以前不熟悉Scala并且想要了解语言的人现在必须理解方法签名,例如:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
Run Code Online (Sandbox Code Playgroud)
对于这样简单的功能,这是一个令人生畏的签名,我发现自己很难理解.并不是说我认为Scala有可能成为下一个Java(或/ C/C++/C#) - 我不相信它的创建者会瞄准那个市场 - 但我认为Scala成为/当然是可行的下一个Ruby或Python(即获得重要的商业用户群)
Steve Yegge 曾经因为他过于复杂的类型系统而攻击Scala(在我看来是错误的).我担心有人会在这个API上传播FUD(类似于Josh Bloch如何通过向Java添加闭包来吓唬JCP).
注意 - 我应该清楚,虽然我相信约书亚布洛赫在拒绝BGGA关闭提案方面具有影响力,但我并没有将此归因于他诚实地认为提案代表错误的其他信息.
尽管我的妻子和同事一直在告诉我,我不认为我是一个白痴:我在牛津大学获得了很好的数学学位,而且我已经在商业方面进行了近12年的编程,并在斯卡拉进行了大约一年(也是商业上).
请注意,炎症主题标题是关于 20世纪80年代早期英国政党宣言的引文.这个问题是主观的,但这是一个真实的问题,我已经成为CW,我想就此事提出一些意见.
C++中的运算符重载被许多人认为是坏事(tm),并且在新语言中不会重复错误.当然,这是设计Java时专门删除的一个功能.
现在我开始阅读Scala,我发现它看起来非常像运算符重载(虽然从技术上来说它没有运算符重载,因为它没有运算符,只有函数).但是,它似乎与C++中的运算符重载没有本质上的区别,因为我记得运算符被定义为特殊函数.
所以我的问题是什么使得在Scala中定义"+"的想法比在C++中更好?
我注意到当我使用期望其他函数作为参数的函数时,我有时可以这样做:
someFunction(firstParam,anotherFunction)
Run Code Online (Sandbox Code Playgroud)
但其他时候,编译器给我一个错误,告诉我应该编写一个这样的函数,以便将它视为部分应用的函数:
someFunction(firstParam,anotherFunction _)
Run Code Online (Sandbox Code Playgroud)
例如,如果我有这个:
object Whatever {
def meth1(params:Array[Int]) = ...
def meth2(params:Array[Int]) = ...
}
import Whatever._
val callbacks = Array(meth1 _,meth2 _)
Run Code Online (Sandbox Code Playgroud)
为什么我不能拥有如下代码:
val callbacks = Array(meth1,meth2)
Run Code Online (Sandbox Code Playgroud)
在什么情况下编译器会告诉我添加_?
我想在scala单例类中定义一个看起来像的私有方法;
private def createDomNode(tag: String, attrs: Map[String , String]): DomNode {
}
Run Code Online (Sandbox Code Playgroud)
DomNode是Java类型,而不是scala类型.attrs是scala Map,其键和值都是String类型.
但上面给出了错误.什么是正确的格式?
谢谢Easy Angel的答案.仍有一些困惑.根据该语言的发明者编写的Scala编程书,下面是一个函数:
def max(x: Int, y: Int): Int = {
if (x > y) x
else y
}
Run Code Online (Sandbox Code Playgroud)
但是你的回答是它是方法而不是功能.你能解释一下吗?
什么是REPL?
在Scala中可以通过多种方式定义函数,这会导致混淆何时需要确切的函数参数类型.我通常从最简单的可能定义开始,然后向下工作直到编译器错误消失.我宁愿真正理解这是如何工作的.
例如:
_ + _
(x, y) => x + y
(x: Int, y: Int) => x + y
def sum(x: Int, y: Int) = x + y // as pointed out, this is a method,
// which not a function
Run Code Online (Sandbox Code Playgroud)
奖励指向文档的链接.
我刚刚在Scala actors包中看到过这个case类:
case class ! [a](ch: Channel[a], msg: a)
Run Code Online (Sandbox Code Playgroud)
在JavaDoc中,它以下列形式描述了用法:
receive {
case Chan1 ! msg1 => ...
case Chan2 ! msg2 => ...
}
Run Code Online (Sandbox Code Playgroud)
为什么不是这样的:
receive {
case !(Chan1, msg1) => ...
case !(Chan2, msg2) => ...
}
Run Code Online (Sandbox Code Playgroud)
是砰的操作员!与以冒号结尾的方法类似的特殊情况: