我在Scala 2.7.5中编写了一个相当大的程序,现在我期待2.8版本。但我很好奇Scala演变的这一重大飞跃将如何影响我。
这两个版本的Scala之间最大的区别是什么?也许最重要的是:
答案 0 :(得分:37)
迁移时,编译器可以为您提供一些安全网。
-deprecation
,并按照
所有弃用的建议
警告。 更新您要使用的代码 没有包装的。这可以做到 通过反复运行机械地 这个正则表达式搜索 取代
s/^(package com.example.project.*)\.(\w+)/$1\npackage $2/g
使用偏执命令行选项编译2.8.0编译器-deprecation -Xmigration -Xcheckinit -Xstrict-warnings -Xwarninit
如果收到错误could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T]
,则需要在类型参数上添加隐式参数(或等效地,上下文绑定)。
在:
scala> def listToArray[T](ls: List[T]): Array[T] = ls.toArray
<console>:5: error: could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T]
def listToArray[T](ls: List[T]): Array[T] = ls.toArray ^
后:
scala> def listToArray[T: Manifest](ls: List[T]): Array[T] = ls.toArray
listToArray: [T](ls: List[T])(implicit evidence$1: Manifest[T])Array[T]
scala> def listToArray[T](ls: List[T])(implicit m: Manifest[T]): Array[T] = ls.toArray
listToArray: [T](ls: List[T])(implicit m: Manifest[T])Array[T]
任何调用listToArray
并且本身将T
作为类型参数的方法,也必须接受Manifest作为隐式参数。有关详细信息,请参阅Arrays SID。
不久之后,您会遇到如下错误:
scala> collection.Map(1 -> 2): Map[Int, Int]
<console>:6: error: type mismatch;
found : scala.collection.Map[Int,Int]
required: Map[Int,Int]
collection.Map(1 -> 2): Map[Int, Int]
^
您需要了解类型Map
是Predef中collection.immutable.Map
的别名。
object Predef {
type Map[A, B] = collection.immutable.Map[A, B]
val Map = collection.immutable.Map
}
有三种类型Map
- 只读接口:collection.Map
,不可变实现:collection.immutable.Map
,以及可变实现:collection.mutable.Map
。此外,库定义了一组并行的特征MapLike
中的行为,但这实际上是一个实现细节。
使用生成的copy
案例类方法。
scala> case class Foo(a: Int, b: String)
defined class Foo
scala> Foo(1, "a").copy(b = "b")
res1: Foo = Foo(1,b)
List
推广到Seq
或Iterable
或Traversable
。由于集合类处于干净的层次结构中,您是否可以接受更通用的类型。您可以在开始迁移时安全地忽略许多其他新功能,例如@specialized
和Continuations。
答案 1 :(得分:33)
您可以在这里找到preview of new feature in Scala2.8(2009年4月),最近this article完成(2009年6月)
“重写代码”不是义务(除了使用一些改进的集合),但有一些功能,如 continuation (Wikipedia:抽象表示控制状态,或“其余的计算”或“要执行的其余代码”)可以给你一些新的想法。一个很好的介绍是found here,由Daniel编写(他在这个帖子中也发布了很多more detailed and specific answer)。
注意:Scala on Netbeans似乎适用于2.8夜间构建(与official page for 2.7.x相比)
答案 2 :(得分:25)
VonC的答案很难改进,所以我甚至都不会尝试。我将介绍他未提及的其他一些内容。
首先,一些不赞成的东西会消失。如果您的代码中有弃用警告,则可能不再编译。
接下来,Scala的库正在扩展。通常,常见的小模式,例如将异常捕获到Either
或Option
,或将AnyRef转换为null
映射到None
的选项。这些东西大部分都可以忽略不计,但我已经厌倦了在博客上发布内容,后来有人告诉我它已经在Scala 2.8上了。嗯,实际上,我并没有感到厌倦,而是,幸运地,习惯了它。我不是在这里谈论收藏品, 正在进行重大修订。
现在,如果人们发布了这些图书馆改进的实际例子作为答案, 会很好。我很乐意提出所有这些答案。
REPL不仅仅是命令完成。它获得了很多东西,包括能够检查对象的AST,或者能够将断点插入到落入REPL的代码中。
此外,Scala的编译器正在被修改为能够为IDE提供快速的部分编译,这意味着我们可以期望它们变得更加“了解”Scala - 通过查询Scala编译器本身的代码。
一个很大的变化可能会被许多人忽视,尽管它会减少图书馆作家和用户的问题。现在,如果您写下以下内容:package com.mystuff.java.wrappers
import java.net._
您导入的不是Java的net
库,而是com.mystuff.java
的{{1}}库,net
,com
,com.mystuff
和{ {1}}都在范围内,com.mystuff.java
可以在com.mystuff.java.wrappers
内找到。使用Scala 2.8,只有java
获得范围。由于有时您希望其余部分在Scope中,因此现在允许使用替代com.mystuff
语法:
wrappers
相当于:
package
恰好将package com.mystuff.factories
package ligthbulbs
和package com.mystuff.factories {
package lightbulbs {
...
}
}
纳入范围。
答案 3 :(得分:11)
我需要重写任何内容吗?
def takesArray(arr: Array[AnyRef]) {…}
def usesVarArgs(obs: AnyRef*) {
takesArray(obs)
}
需要成为
def usesVarArgs(obs: AnyRef*) {
takesArray(obs.toArray)
}
我必须访问那个IRC频道,但后来意识到我应该从这里开始。
答案 4 :(得分:6)
这是Eric Willigers的清单,自2.2以来一直使用Scala。其中一些内容似乎可以追溯到最近的用户。
*明确从外包装中导入*
假设我们有
package a
class B
更改
package a.c
class D extends B
到
package a.c
import a.B
class D extends B
或
package a
package c
class D extends B
*从外部包*
导入时使用完全限定的包名称假设我们有
package a.b
object O { val x = 1 }
更改
package a.b.c
import b.O.x
到
package a.b.c
import a.b.O.x
*在容器方法调用中显式指定类型参数时,添加新类型参数*
更改
list.map[Int](f)
到
list.map[Int, List[Int]](f)
更改
map.transform[Value](g)
到
map.transform[Value, Map[Key, Value]](g)
*使用订购创建有序地图,而不是转换为有序*
[scalac] found : (String) => Ordered[String]
[scalac] required: Ordering[String]
[scalac] TreeMap[String, Any](map.toList: _*)(stringToCaseInsensitiveOrdered _)
*导入替换scala.collection.jcl的隐式转换*
*不可变地图.update变为.updated *
***从新弃用的List方法迁移 -
*elements
*remove
*sort
*List.flatten(someList)
*List.fromString(someList, sep)
*List.make
***使用List方法 *
diff
*iterator
*filterNot
*sortWith
*someList.flatten
*someList.split(sep)
*List.fill
*使用scala.tools.nsc.Settings *时的类路径
http://thread.gmane.org/gmane.comp.lang.scala/18245/focus=18247 settings.classpath.value = System.getProperty(“java.class.path”)
*避免错误:_必须遵循方法;不能跟随(任何)=&gt;布尔*
替换
list.filter(that.f _)
与
list.filter(that f _)
或
list.filter(that.f(_))
&GT; &GT; &GT;
*从弃用的枚举方法迁移
iterator
map
* 使用枚举方法values.iterator
values.map
*从已弃用的
Iterator.fromValues(a, b, c, d)
* 迁移 使用Iterator(a, b, c, d)
*避免弃用类型
Collection
* 请改用Iterable
*更改初始化订单*
假设我们有
trait T {
val v
val w = v + v
}
替换
class C extends T {
val v = "v"
}
与
class C extends {
val v = "v"
} with T
*在
中避免不需要val
*for (val x <- ...)
*避免使用逗号*