Scala 2.8和Scala 2.7之间最大的区别是什么?

And*_*zlo 58 scala

我在Scala 2.7.5中编写了一个相当大的程序,现在我期待2.8版本.但我很好奇Scala演变的这一重大飞跃将如何影响我.

这两个版本的Scala之间最大的区别是什么?也许最重要的是:

  • 需要重写一下吗?
  • 重写任何东西只是为了利用一些很酷的新功能吗?
  • 一般来说,Scala 2.8的新功能究竟是什么?

ret*_*nym 37

迈出了一步

迁移时,编译器可以为您提供一些安全网.

  1. 使用2.7.7编译旧代码-deprecation,并遵循所有弃用警告中的建议.
  2. 更新代码以使用未经编辑的软件包.这可以通过重复运行此正则表达式搜索替换来机械地完成.

    s/^(package com.example.project.*)\.(\w+)/$1\npackage $2/g
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用偏执命令行选项编译2.8.0编译器 -deprecation -Xmigration -Xcheckinit -Xstrict-warnings -Xwarninit

  4. 如果您收到错误错误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.

  5. 不久之后,你会遇到这样的错误:

    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,但这实际上是一个实现细节.

收获利益

  1. 用named和default参数替换一些方法重载.
  2. 使用生成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)
  3. 将方法签名概括ListSeqIterableTraversable.由于集合类处于干净的层次结构中,您是否可以接受更通用的类型.
  4. 使用Annotations与Java库集成.您现在可以指定嵌套注释,并对注释是否以字段或方法为目标进行细粒度控制.这有助于将Spring或JPA与Scala代码一起使用.

当您开始迁移时,可以安全地忽略许多其他新功能,例如@specializedContinuations.


Von*_*onC 33

您可以在此处找到Scala2.8(2009年4月)中新功能预览,最近完成了本文(2009年6月)

  • 命名和默认参数
  • 嵌套注释
  • 包对象
  • @专门
  • 改进的集合(这里可能需要重写一些)
  • REPL将完成命令(更多内容和本文中的其他技巧)
  • 新的控制抽象(延续或休息)
  • 增强功能(Swing包装,性能......)

"重写代码"不是义务(除了使用一些改进的集合),但是一些功能如延续(维基百科:控件状态的抽象表示,或"其余计算"或"要执行的其余代码" ")可以给你一些新的想法.这里有一个很好的介绍,由丹尼尔撰写(他也在这个帖子中发布了更为详细和具体的答案).

注意:Netbeans上的Scala似乎可以使用2.8夜间版本(相对于2.7.x官方页面)


Dan*_*ral 25

VonC的答案很难改进,所以我甚至都不会尝试.我将介绍他未提及的其他一些内容.

首先,一些被弃用的东西将会消失.如果您的代码中有弃用警告,则可能不再编译.

接下来,Scala的库正在扩展.大多数情况下,常见的小模式,如将异常捕获到EitherOption,或将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.javanet图书馆,如com,com.mystuff,com.mystuff.javacom.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)

并碰巧得到两者factorieslightbulbs进入范围.


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频道,但后来意识到我应该从这里开始.


Dan*_*ral 6

这是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)

*避免不必要valfor (val x <- ...)*

*避免使用逗号*