Каковы самые большие различия между Scala 2.8 и Scala 2.7? - PullRequest
58 голосов
/ 07 августа 2009

Я написал довольно большую программу на Scala 2.7.5, и теперь я с нетерпением жду версии 2.8. Но мне любопытно, как этот большой скачок в эволюции Scala повлияет на меня.

Что будет самым большим отличием между этими двумя версиями Scala? И, возможно, самое главное:

  • Нужно ли мне , чтобы что-нибудь переписать?
  • Хочу ли я хотеть что-нибудь переписать, просто чтобы воспользоваться какой-нибудь интересной новой функцией?
  • Каковы в целом новые функции Scala 2.8?

Ответы [ 5 ]

37 голосов
/ 31 марта 2010

Прыжок

При переносе компилятор может предоставить вам несколько сетей безопасности.

  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 в качестве параметра типа, также должен принимать манифест в качестве неявного параметра. Подробнее см. 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
     }
    

    Существует три типа с именем 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 с использованием аннотаций. Теперь вы можете указывать вложенные аннотации и иметь детальный контроль над тем, предназначены ли аннотации для полей или методов. Это помогает использовать Spring или JPA с кодом Scala.

Существует множество других новых функций, которые можно безопасно игнорировать при начале миграции, например, @specialized и Continuations.

33 голосов
/ 07 августа 2009

Здесь вы можете просмотреть предварительный просмотр новой функции в Scala2.8 (апрель 2009 г.), дополненный недавней этой статьей (июнь 2009 г.)

  • Именованные и стандартные аргументы
  • Вложенные аннотации
  • Пакет объектов
  • @ специализированы
  • Улучшенные коллекции (здесь может потребоваться некоторая перезапись)
  • У REPL будет завершение команды (подробнее об этом и других трюках в этой статье )
  • Новые контрольные абстракции (продолжение или перерыв)
  • Улучшения (Swing wrapper, перформансы, ...)

«Код перезаписи» не является обязательным (за исключением использования некоторых из улучшенных Коллекций), но некоторые функции, такие как продолжение ( Википедия : реферат представление состояния управления, или «остальная часть вычислений» или «остальная часть кода, который будет выполнен») может дать вам несколько новых идей. Хорошим введением является , найденное здесь , написанное Daniel (который также опубликовал более более подробный и конкретный ответ в этой теме).

Примечание: Scala на NetBeans , кажется, работает с некоторыми 2.8 ночными сборками (по сравнению с официальной страницей для 2.7.x )

25 голосов
/ 07 августа 2009

Ответ VonC трудно улучшить, поэтому я даже не буду пытаться. Я расскажу о некоторых других вещах, не упомянутых им.

Сначала пойдут некоторые устаревшие вещи. Если в вашем коде есть предупреждения об устаревании, скорее всего, он больше не будет компилироваться.

Далее библиотека Scala расширяется. В основном это обычные небольшие шаблоны, такие как перехват исключений в Either или Option или преобразование AnyRef в Option с null, сопоставленным с None. Эти вещи в основном могут остаться незамеченными, но я устаю от публикации чего-либо в блоге, а потом от того, чтобы кто-то сказал мне, что это уже на Scala 2.8. Ну, на самом деле, я не устаю от этого, но, к счастью, привык к этому. И я не говорю здесь о коллекциях, которые получают серьезную ревизию.

Теперь, было бы хорошо, если бы люди опубликовали реальные примеры таких улучшений библиотеки в качестве ответов. Я бы с радостью одобрил все такие ответы.

REPL не получает просто завершение команды. Он получает много вещей, включая возможность проверять AST на предмет или возможность вставлять точки останова в код, попадающий в REPL.

Кроме того, компилятор Scala модифицируется, чтобы обеспечить быструю частичную компиляцию для IDE, что означает, что мы можем ожидать, что они станут намного более «осведомленными» о Scala - запрашивая у самого компилятора Scala код. *

Одно большое изменение, вероятно, останется незамеченным многими, хотя оно уменьшит проблемы как для авторов библиотеки, так и для пользователей. Прямо сейчас, если вы напишите следующее:

package com.mystuff.java.wrappers

import java.net._

Вы импортируете не библиотеку net Java, а библиотеку 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

, что эквивалентно:

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

И случается, что оба factories и lightbulbs попадают в область видимости.

11 голосов
/ 10 ноября 2009

Нужно ли мне , чтобы что-нибудь переписать?

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

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

должно стать

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

Я должен был посетить канал IRC для этого, но потом понял, что я должен был начать здесь.

6 голосов
/ 31 марта 2010

Вот контрольный список от Эрика Виллигерса, который использует Scala с 2.2. Некоторые из этих материалов покажутся более новыми пользователями.

* Явный импорт из внешних пакетов *

Предположим, у нас есть

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 *

* Неизменяемая карта. Обновление становится. Обновление *

*** Миграция из новых устаревших методов 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) * Используйте 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 <- ...) *

* Избегайте запятых *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...