代码之家  ›  专栏  ›  技术社区  ›  André Laszlo

scala 2.8和scala 2.7最大的区别是什么?

  •  58
  • André Laszlo  · 技术社区  · 15 年前

    我已经用scala 2.7.5编写了一个相当大的程序,现在我期待着2.8版。但我很好奇斯卡拉进化过程中的这一大步会对我产生怎样的影响。

    这两个版本的scala最大的区别是什么?或许最重要的是:

    • 我会 需要 重写什么?
    • 我做 希望 为了利用一些很酷的新功能而重写任何东西?
    • scala 2.8的新特性到底是什么?
    5 回复  |  直到 13 年前
        1
  •  33
  •   Community Egal    7 年前

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

    • 命名参数和默认参数
    • 嵌套注释
    • 包对象
    • @专业化
    • 改进的集合(此处可能需要一些重写)
    • repl将完成命令(更多 on that and other tricks in this article )
    • 新控件抽象(继续或中断)
    • 增强功能(Swing Wrapper、性能…)

    “重写代码”不是一项义务(除了使用一些改进的集合),而是一些功能,例如 continuation ( Wikipedia :控制状态的抽象表示、“剩余计算”或“要执行的剩余代码”)可以为您提供一些新的想法。一个好的介绍是 found here ,由 Daniel (谁也张贴了很多 more detailed and specific answer 在这个线程中)。

    注: Scala on Netbeans 似乎适合每晚2.8个版本(与 official page for 2.7.x )

        2
  •  37
  •   retronym    14 年前

    跃跃欲试

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

    1. 根据2.7.7编译旧代码 具有 -deprecation ,然后按照 所有折旧建议 警告。
    2. 更新代码以使用 未连接的包。这可以做到 通过反复运行实现机械化 此正则表达式搜索 替换。

      s/^(package com.example.project.*)\.(\w+)/$1\npackage $2/g
      
    3. 使用2.8.0编译器编译,使用paranoid命令行选项 -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                                              ^
      

      后:

      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 作为类型参数,还必须接受清单作为隐式参数。见 Arrays 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]
                   ^
      

      你需要理解的是 Map 是predef中的别名 collection.immutable.Map .

       object Predef {
           type Map[A, B] = collection.immutable.Map[A, B]
           val Map = collection.immutable.Map
       }
      

      有三种类型 地图 --只读接口: collection.Map ,一个不变的实现: collection.immutable.map 和可变实现: collection.mutable.Map . 此外,库定义了一组并行特征中的行为。 MapLike 但这确实是一个实现细节。

    收获利益

    1. 用命名参数和默认参数替换某些方法重载。
    2. 使用生成的 copy case类的方法。

        scala> case class Foo(a: Int, b: String)
        defined class Foo
      
        scala> Foo(1, "a").copy(b = "b")
        res1: Foo = Foo(1,b)
      
    3. 归纳方法签名 List Seq Iterable Traversable . 因为集合类在一个干净的层次结构中,所以您可以接受更一般的类型吗?
    4. 使用注释与Java库集成。现在可以指定嵌套注释,并且 fine-grained control 注释是否针对字段或方法。这有助于在scala代码中使用spring或jpa。

    例如,在开始迁移时,可以安全地忽略许多其他新功能。 @specialized 以及延续。

        3
  •  25
  •   Daniel C. Sobral    15 年前

    VONC的答案很难改进,所以我甚至不会尝试。我会介绍一些他没有提到的东西。

    首先,一些被否决的东西会消失。如果您的代码中有拒绝警告,那么它可能不会再编译了。

    接下来,scala的库将被扩展。大多数情况下,常见的小模式,如将异常捕获到 Either Option 或将anyRef转换为选项 null 映射到 None . 这些事情基本上可以忽略不计,但我厌倦了在博客上发布一些东西,后来有人告诉我它已经在scala 2.8上了。嗯,事实上,我没有 疲倦的 但是,更确切地说,快乐的是,它已经习惯了。我不是在这里谈论这些收藏品, 正在进行重大修订。

    现在,它 如果人们把图书馆改进的实际例子作为答案,那就好了。我很乐意推翻所有这些答案。

    repl不只是完成命令。它得到了很多东西,包括检查对象的AST的能力,或者向repl中的代码插入断点的能力。

    此外,scala的编译器正在被修改,以便能够为IDES提供快速的部分编译,这意味着通过查询scala编译器本身的代码,我们可以期望它们对scala有更多的“了解”。

    一个巨大的变化可能会被许多人忽视,尽管它会减少图书馆作家和用户的问题。现在,如果您写下以下内容:

    package com.mystuff.java.wrappers
    
    import java.net._
    

    您导入的不是Java的 net 图书馆,但 com.mystuff.java 作为图书馆 com , com.mystuff , java网站 com.mystuff.java.wrappers 都在范围内,而且 java 可以在里面找到 MyStudio . 只有scala 2.8 wrappers 获取范围。因为,有时,您希望其他部分在范围内,这是另一种选择 package 现在允许使用语法:

    package com.mystuff.factories
    package ligthbulbs
    

    相当于:

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

    两个都有 factories lightbulbs 进入范围。

        4
  •  11
  •   Bart Schuller    15 年前

    我会 需要 重写什么?

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

    需要成为

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

    我必须去IRC频道看一看,但后来意识到我应该从这里开始。

        5
  •  6
  •   Daniel C. Sobral    14 年前

    这是EricWilligers的清单,他从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的隐式转换*

    *不可变的map.update变为.updated*

    ***从新弃用的列表方法迁移--
    * 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时的类路径*

    http://thread.gmane.org/gmane.comp.lang.scala/18245/focus=18247

    *避免错误:u must follow method;cannot follow(any)=>boolean*

    替换

    list.filter(that.f _)
    

    具有

    list.filter(that f _)
    

    list.filter(that.f(_))
    

    > gt; gt;

    *从已弃用的枚举方法迁移 迭代器 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 <- ...) *

    *避免尾随逗号*