Scala 2.8和Scala 2.7最大的区别是什么?
我在Scala 2.7.5中写了一个相当大的程序,现在我期待2.8版本。 但是我很好奇Scala的这个巨大的飞跃将会如何影响我。
这两个版本的Scala最大的区别是什么? 也许最重要的是:
- 我需要重写什么吗?
- 我想重写任何东西只是为了利用一些很酷的新function吗?
- Scala 2.8的新特性究竟是什么?
您可以在这里findScala2.8 (2009年4月) 的新function预览,最近完成了这篇文章 (2009年6月)
- 命名和默认参数
- 嵌套注释
- 包对象
- @专门
- 改进的集合(这里可能需要重写)
- REPL将有命令完成(更多在这篇文章和其他技巧 )
- 新的控制抽象(继续或中断)
- 增强(Swing包装,表演,…)
“重写代码”不是一个义务(除了使用一些改进的集合),但是一些特性如继续 ( 维基百科 :控制状态的抽象表示,或者“剩余的计算”或“要执行的代码的其余部分“)可以给你一些新的想法。 在这里可以find一个很好的介绍,由丹尼尔 (在这个post中也发布了更详细和具体的答案 )写的。
注意: Netbeans上的Scala似乎可以在每晚2.8版本( 2.7.x的官方页面 )
跨越式发展
当您迁移时,编译器可以为您提供一些安全网。
- 用
-deprecation
编译2.7.7的旧代码,并按照所有弃用警告中的build议进行操作。 -
更新您的代码以使用unnnested包。 这可以通过重复运行这个正则expression式searchreplace来机械地完成。
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]
,则需要在types参数上添加一个隐式参数(或等同于上下文绑定)。之前:
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
作为types参数,也必须接受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
types是Predef中用于collection.immutable.Map
的别名。object Predef { type Map[A, B] = collection.immutable.Map[A, B] val Map = collection.immutable.Map }
有三种名为
Map
types – 一个只读接口:collection.Map
,一个不可变的实现:collection.immutable.Map
,以及一个可变的实现:collection.mutable.Map
。 此外,图书馆定义了一组并行的MapLike
行为,但这实际上是一个实现细节。
获得好处
- 用命名参数和默认参数replace一些重载方法。
-
使用生成的案例类的
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
。 由于集合类是在一个干净的层次结构中,你可以接受一个更一般的types。 - 使用注释与Java库集成。 您现在可以指定嵌套的注释,并且对注释是针对字段还是方法进行细化控制 。 这有助于使用Spring或JPA与Scala代码。
还有许多其他新function可以在开始迁移时安全地忽略,例如@specialized
和Continuations。
VonC的答案很难改善,所以我甚至不会去尝试。 我会介绍一些他没有提到的其他东西。
首先,一些弃用的东西会去。 如果您的代码中存在弃用警告,则很可能无法再编译。
接下来,斯卡拉的图书馆正在扩大。 大多数情况下,常见的小模式,例如将exception捕获到Either
或Option
,或将AnyRef转换成null
映射到None
的Option。 这些东西大多可以忽略,但是我厌倦了在博客上发布一些东西,后来有人告诉我它已经在Scala 2.8上。 实际上,我并没有厌倦它,而是,而且很高兴地习惯了它。 我在这里不是在谈论collections,这是一个重大的修订。
现在,如果有人把这种图书馆改进的实际例子作为答案,那将是很好的。 我很乐意提出所有这样的答案。
REPL不仅仅是命令完成。 它获得了很多东西,包括检查对象的AST的能力,或者将断点插入到REPL代码中的能力。
此外,Scala的编译器正在被修改,以便能够对IDE进行快速部分编译,这意味着我们可以期望它们对Scala变得更加“认识” – 通过查询Scala编译器本身的代码。
一个巨大的变化可能会被很多人忽视,尽pipe这会减less图书馆作者和用户的问题。 现在,如果你写下以下内容:
package com.mystuff.java.wrappers import java.net._
您不是导入Java的net
库,而是com.mystuff.java
的net
库,如com
, com.mystuff
, com.mystuff.java
和com.mystuff.java.wrappers
都在范围内,并且可以在内部findjava
com.mystuff
。 随着Scala 2.8,只有wrappers
获得范围。 因为有时候,你希望其余的一些在Scope中,所以现在可以使用一个替代的package
语法:
package com.mystuff.factories package ligthbulbs
相当于:
package com.mystuff.factories { package lightbulbs { ... } }
碰巧把factories
和lightbulbs
纳入了范围。
我需要重写什么吗?
def takesArray(arr: Array[AnyRef]) {…} def usesVarArgs(obs: AnyRef*) { takesArray(obs) }
需要成为
def usesVarArgs(obs: AnyRef*) { takesArray(obs.toArray) }
我不得不去访问那个IRC频道,但后来意识到我应该从这里开始。
这里有一个Eric Willigers的清单,他从2.2开始就一直在使用Scala。 这些东西中的一些似乎过时了更近的用户。
*从外包显式导入*
假设我们有
package a class B
更改
package ac class D extends B
至
package ac import aB class D extends B
要么
package a package c class D extends B
*从外包装import时使用完全合格的包装名称*
假设我们有
package ab object O { val x = 1 }
更改
package abc import bOx
至
package abc import abOx
*在容器方法调用中明确指定types参数时,添加新的types参数*
更改
list.map[Int](f)
至
list.map[Int, List[Int]](f)
更改
map.transform[Value](g)
至
map.transform[Value, Map[Key, Value]](g)
*使用sorting创buildsorting的地图,而不是转换为sorting*
[scalac] found : (String) => Ordered[String] [scalac] required: Ordering[String] [scalac] TreeMap[String, Any](map.toList: _*)(stringToCaseInsensitiveOrdered _)
*导入replacescala.collection.jcl的隐式转换*
* Immutable Map .update变成.update *
***从新弃用的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时的类path*
http://thread.gmane.org/gmane.comp.lang.scala/18245/focus=18247 settings.classpath.value = System.getProperty(“java.class.path”)
*避免错误:_必须遵循方法; 不能跟随(任何)=>布尔*
更换
list.filter(that.f _)
同
list.filter(that f _)
要么
list.filter(that.f(_))
>>>
从不推荐使用的枚举方法
iterator
map
*使用枚举方法values.iterator
values.map
Iterator.fromValues(a, b, c, d)
从Iterator(a, b, c, d)
*避免不build议使用的types
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 <- ...)
**避免尾随逗号*