首页 文章

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

提问于
浏览
58

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

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

  • 我需要重写一下吗?

  • 我想重写任何东西只是为了利用一些很酷的新功能吗?

  • Scala 2.8的新功能究竟是什么?

5 回答

  • 33

    你可以在这里找到preview of new feature in Scala2.8(2009年4月),最近完成this article(2009年6月)

    • 命名和默认参数

    • 嵌套注释

    • 包对象

    • @specialized

    • 改进的集合(这里可能需要重写一些)

    • REPL将完成命令(更多on that and other tricks in this article

    • 新控制抽象(继续或休息)

    • 增强功能(摆动包装,演奏......)

    "Rewriting code"不是义务(除了使用一些改进的集合),但某些功能如 continuationWikipedia:控件状态的抽象表示,或"rest of computation"或"rest of code to be executed")可以为您提供一些新的想法 . 一个很好的介绍是found here,由Daniel撰写(他在这个帖子中也发布了很多more detailed and specific answer) .

    注意:Scala on Netbeans似乎适用于2.8夜间构建(与official page for 2.7.x相比)

  • 37

    迈出了一步

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

    • 使用 -deprecation 将旧代码编译为2.7.7,并遵循所有弃用警告中的建议 .

    • 更新代码以使用未经编辑的软件包 . 这可以通过重复运行此正则表达式搜索替换来机械地完成 .

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

    收获利益

    • 使用named和default参数替换某些方法重载 .

    • 使用生成的 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 概括为 SeqIterableTraversable . 由于集合类处于干净的层次结构中,您是否可以接受更通用的类型 .

    • 使用Annotations与Java库集成 . 您现在可以指定嵌套注释,并且注释是否针对字段或方法具有fine-grained control . 这有助于将Spring或JPA与Scala代码一起使用 .

    在开始迁移时,可以安全地忽略许多其他新功能,例如 @specialized 和Continuations .

  • 11

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

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

    接下来,Scala的库正在扩展 . 通常,常见的小模式,例如将异常捕获到 EitherOption ,或将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.javanet 库,因为 comcom.mystuffcom.mystuff.javacom.mystuff.java.wrappers 都在范围内,并且 java 可以在 com.mystuff 中找到 . 使用Scala 2.8,只有 wrappers 获得范围 . 由于有时您希望其余部分在Scope中,因此现在允许使用另一种语法:

    package com.mystuff.factories
    package ligthbulbs
    

    这相当于:

    package com.mystuff.factories {
      package lightbulbs {
        ...
      }
    }
    

    碰巧将 factorieslightbulbs 都纳入范围 .

  • 25

    我需要重写任何内容吗?

    def takesArray(arr: Array[AnyRef]) {…}
    
    def usesVarArgs(obs: AnyRef*) {
        takesArray(obs)
    }
    

    需要成为

    def usesVarArgs(obs: AnyRef*) {
        takesArray(obs.toArray)
    }
    

    我不得不访问那个IRC Channels ,但后来意识到我应该从这里开始 .

  • 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)
    

    使用订购创建有序 Map ,而不是转换为有序

    [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 使用列表方法 diff * iterator * filterNot * sortWith * someList.flatten * someList.split(sep) List.fill * classpath使用scala.tools.nsc.Settings时 http://thread.gmane.org/gmane.comp.lang.scala/18245/focus=18247 settings.classpath.value = System.getProperty(“java.class.path”)*避免错误:_必须遵循方法;无法跟随(Any)=> Boolean *替换

    list.filter(that.f _)
    

    list.filter(that f _)
    

    list.filter(that.f(_))
    

    *从弃用的枚举方法迁移iterator map *使用枚举方法values.iterator values.map 从弃用的Iterator.fromValues迁移(a,b,c,d)使用迭代器(a,b,c,d)避免弃用类型集合使用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(val x < - ...) 避免使用尾随逗号

相关问题