我在Scala 2.7.5中编写了一个相当大的程序,现在我期待2.8版本.但我很好奇Scala演变的这一重大飞跃将如何影响我.
这两个版本的Scala之间最大的区别是什么?也许最重要的是:
ret*_*nym 37
迁移时,编译器可以为您提供一些安全网.
-deprecation
,并遵循所有弃用警告中的建议.更新代码以使用未经编辑的软件包.这可以通过重复运行此正则表达式搜索替换来机械地完成.
s/^(package com.example.project.*)\.(\w+)/$1\npackage $2/g
Run Code Online (Sandbox Code Playgroud)使用偏执命令行选项编译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 ^
Run Code Online (Sandbox Code Playgroud)
后:
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]
Run Code Online (Sandbox Code Playgroud)
任何调用的方法listToArray
,以及它本身T
作为类型参数,都必须接受Manifest作为隐式参数.有关详细信息,请参阅阵列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]
^
Run Code Online (Sandbox Code Playgroud)
您需要了解该类型Map
是Predef中的别名collection.immutable.Map
.
object Predef {
type Map[A, B] = collection.immutable.Map[A, B]
val Map = collection.immutable.Map
}
Run Code Online (Sandbox Code Playgroud)
有三种类型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)
Run Code Online (Sandbox Code Playgroud)List
为Seq
或Iterable
或Traversable
.由于集合类处于干净的层次结构中,您是否可以接受更通用的类型.当您开始迁移时,可以安全地忽略许多其他新功能,例如@specialized
Continuations.
Von*_*onC 33
您可以在此处找到Scala2.8(2009年4月)中新功能的预览,最近完成了本文(2009年6月)
"重写代码"不是义务(除了使用一些改进的集合),但是一些功能如延续(维基百科:控件状态的抽象表示,或"其余计算"或"要执行的其余代码" ")可以给你一些新的想法.这里有一个很好的介绍,由丹尼尔撰写(他也在这个帖子中发布了更为详细和具体的答案).
注意:Netbeans上的Scala似乎可以使用2.8夜间版本(相对于2.7.x的官方页面)
Dan*_*ral 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._
Run Code Online (Sandbox Code Playgroud)
您正在导入没有Java的net
库,但com.mystuff.java
的net
图书馆,如com
,com.mystuff
,com.mystuff.java
和com.mystuff.java.wrappers
范围内的所有找来的,java
里面可以找到com.mystuff
.使用Scala 2.8,只能wrappers
获得范围.由于有时您希望其余部分在Scope中,package
因此现在允许使用替代语法:
package com.mystuff.factories
package ligthbulbs
Run Code Online (Sandbox Code Playgroud)
这相当于:
package com.mystuff.factories {
package lightbulbs {
...
}
}
Run Code Online (Sandbox Code Playgroud)
并碰巧得到两者factories
并lightbulbs
进入范围.
Bar*_*ler 11
我需要重写一下吗?
def takesArray(arr: Array[AnyRef]) {…}
def usesVarArgs(obs: AnyRef*) {
takesArray(obs)
}
Run Code Online (Sandbox Code Playgroud)
需要成为
def usesVarArgs(obs: AnyRef*) {
takesArray(obs.toArray)
}
Run Code Online (Sandbox Code Playgroud)
我不得不访问那个IRC频道,但后来意识到我应该从这里开始.
这是Eric Willigers的清单,自2.2以来一直使用Scala.其中一些东西似乎可以追溯到最近的用户.
*明确从外包装进口*
假设我们有
package a
class B
Run Code Online (Sandbox Code Playgroud)
更改
package a.c
class D extends B
Run Code Online (Sandbox Code Playgroud)
至
package a.c
import a.B
class D extends B
Run Code Online (Sandbox Code Playgroud)
要么
package a
package c
class D extends B
Run Code Online (Sandbox Code Playgroud)
*从外包装导入时使用完全限定的包装名称*
假设我们有
package a.b
object O { val x = 1 }
Run Code Online (Sandbox Code Playgroud)
更改
package a.b.c
import b.O.x
Run Code Online (Sandbox Code Playgroud)
至
package a.b.c
import a.b.O.x
Run Code Online (Sandbox Code Playgroud)
*在容器方法调用中显式指定类型参数时,添加新类型参数*
更改
list.map[Int](f)
Run Code Online (Sandbox Code Playgroud)
至
list.map[Int, List[Int]](f)
Run Code Online (Sandbox Code Playgroud)
更改
map.transform[Value](g)
Run Code Online (Sandbox Code Playgroud)
至
map.transform[Value, Map[Key, Value]](g)
Run Code Online (Sandbox Code Playgroud)
*使用订购创建有序地图,而不是转换为有序*
[scalac] found : (String) => Ordered[String]
[scalac] required: Ordering[String]
[scalac] TreeMap[String, Any](map.toList: _*)(stringToCaseInsensitiveOrdered _)
Run Code Online (Sandbox Code Playgroud)
*导入替换scala.collection.jcl的隐式转换*
*不可变地图.update变为.updated*
***从新弃用的List方法迁移 -
*elements
*remove
*sort
*List.flatten(someList)
*List.fromString(someList, sep)
*List.make
***使用列表方法*
diff
*iterator
*filterNot
*sortWith
*someList.flatten
*someList.split(sep)
*List.fill
*使用scala.tools.nsc.Settings时的classpath*
http://thread.gmane.org/gmane.comp.lang.scala/18245/focus=18247 settings.classpath.value = System.getProperty("java.class.path")
*避免错误:_必须遵循方法; 不能跟随(Any)=>布尔*
更换
list.filter(that.f _)
Run Code Online (Sandbox Code Playgroud)
同
list.filter(that f _)
Run Code Online (Sandbox Code Playgroud)
要么
list.filter(that.f(_))
Run Code Online (Sandbox Code Playgroud)
>>>
*从弃用的枚举方法迁移
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
}
Run Code Online (Sandbox Code Playgroud)
更换
class C extends T {
val v = "v"
}
Run Code Online (Sandbox Code Playgroud)
同
class C extends {
val v = "v"
} with T
Run Code Online (Sandbox Code Playgroud)
*避免不必要
val
的for (val x <- ...)
**避免使用逗号*
归档时间: |
|
查看次数: |
9420 次 |
最近记录: |