J’ai écrit un programme assez volumineux dans Scala 2.7.5, et j’attends maintenant avec impatience la version 2.8. Mais je suis curieux de savoir comment ce grand saut dans l’évolution de Scala va m’affecter.
Quelles seront les plus grandes différences entre ces deux versions de Scala? Et peut-être le plus important:
Vous pouvez trouver ici un aperçu de la nouvelle fonctionnalité de Scala2.8 (avril 2009), complétée par les articles récents (juin 2009).
“Réécrire le code” n’est pas une obligation (sauf pour certaines collections améliorées), mais certaines fonctionnalités comme la continuation ( Wikipedia : une représentation abstraite de l’état de contrôle ou le “rest du calcul” ou “rest du code à exécuter) “) peut vous donner de nouvelles idées. Une bonne introduction est trouvée ici , écrite par Daniel (qui a également posté une réponse beaucoup plus détaillée et spécifique dans ce sujet).
Note: Scala sur Netbeans semble fonctionner avec un build de nuit 2.8 (vs. la page officielle pour 2.7.x )
Lorsque vous migrez, le compilateur peut vous fournir des filets de sécurité.
-deprecation
et suivez les recommandations de tous les avertissements de dépréciation. Mettez à jour votre code pour utiliser des packages non nesteds. Cela peut être fait mécaniquement en exécutant à plusieurs resockets ce remplacement de recherche par expression régulière.
s/^(package com.example.project.*)\.(\w+)/$1\npackage $2/g
Comstackr avec le compilateur 2.8.0, en utilisant les options de ligne de commande paranoïaques -deprecation -Xmigration -Xcheckinit -Xssortingct-warnings -Xwarninit
Si vous recevez des erreurs, l’erreur could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T]
, vous devez append un paramètre implicite (ou, de manière équivalente, une liaison de contexte) sur un paramètre de type.
Avant:
scala> def listToArray[T](ls: List[T]): Array[T] = ls.toArray :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 ^
Après:
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]
Toute méthode qui appelle listToArray
et elle-même prend T
comme paramètre de type doit également accepter le manifeste comme paramètre implicite. Consultez le SID des tableaux pour plus de détails.
Avant trop longtemps, vous rencontrerez une erreur comme celle-ci:
scala> collection.Map(1 -> 2): Map[Int, Int] :6: error: type mismatch; found : scala.collection.Map[Int,Int] required: Map[Int,Int] collection.Map(1 -> 2): Map[Int, Int] ^
Vous devez comprendre que le type Map
est un alias dans Predef pour collection.immutable.Map
.
object Predef { type Map[A, B] = collection.immutable.Map[A, B] val Map = collection.immutable.Map }
Il existe trois types nommés Map
– une interface en lecture seule: collection.Map
, une implémentation immuable: collection.immutable.Map
, et une implémentation mutable: collection.mutable.Map
. De plus, la bibliothèque définit le comportement dans un ensemble parallèle de traits MapLike
, mais il s’agit vraiment d’un détail d’implémentation.
Utilisez la méthode de copy
générée des classes de cas.
scala> case class Foo(a: Int, b: Ssortingng) defined class Foo scala> Foo(1, "a").copy(b = "b") res1: Foo = Foo(1,b)
List
à Seq
ou Iterable
ou Traversable
. Les classes de collecte étant dans une hiérarchie propre, pouvez-vous accepter un type plus général. Il existe de nombreuses autres nouvelles fonctionnalités qui peuvent être ignorées en toute sécurité lorsque vous commencez à migrer, par exemple @specialized
et Continuations.
La réponse de VonC est difficile à améliorer, alors je ne vais même pas essayer. Je couvrirai d’autres choses non mentionnées par lui.
Tout d’abord, certaines choses dépréciées iront. Si vous avez des avertissements de dépréciation dans votre code, il est probable qu’il ne sera plus compilé.
Ensuite, la bibliothèque de Scala se développe. Surtout, les petits motifs courants, tels que la capture des exceptions dans Either
ou Option
, ou la conversion d’un AnyRef en une option avec null
mappé sur None
. Ces choses peuvent généralement passer inaperçues, mais je commence à en avoir marre de poster quelque chose sur le blog et plus tard, demander à quelqu’un de me dire que c’est déjà sur Scala 2.8. Eh bien, en fait, je ne m’en lasse pas, mais plutôt, et heureusement, je m’y suis habitué. Et je ne parle pas ici des collections, qui font l’object d’une révision majeure.
Maintenant, ce serait bien si les gens affichaient des exemples concrets de ces améliorations de bibliothèque. J’accepterais avec plaisir toutes ces réponses.
REPL n’obtient pas seulement l’achèvement des commandes. Cela prend beaucoup de choses, y compris la possibilité d’examiner l’AST pour un object, ou la possibilité d’insérer des points de rupture dans le code qui tombe dans REPL.
En outre, le compilateur de Scala est en cours de modification pour pouvoir fournir une compilation partielle rapide aux IDE, ce qui signifie que nous pouvons nous attendre à ce qu’ils soient bien plus informés sur Scala – en interrogeant le compilateur Scala lui-même sur le code.
Un grand changement est susceptible de passer inaperçu par beaucoup, bien qu’il réduise les problèmes pour les auteurs de bibliothèques et les utilisateurs. En ce moment, si vous écrivez ce qui suit:
package com.mystuff.java.wrappers import java.net._
Vous com.mystuff.java
pas la bibliothèque net
de Java, mais net
bibliothèque net
com.mystuff
, com.mystuff.java
que com
, com.mystuff
, com.mystuff.java
et com.mystuff.java.wrappers
toutes été com.mystuff.java.wrappers
dans la scope et java
se trouve à l’intérieur. com.mystuff
. Avec Scala 2.8, seuls les wrappers
sont ciblés. Étant donné que, parfois, vous souhaitez qu’une partie du rest soit dans Scope, une autre syntaxe de package
est désormais autorisée:
package com.mystuff.factories package ligthbulbs
ce qui équivaut à:
package com.mystuff.factories { package lightbulbs { ... } }
Et il arrive que les factories
et les lightbulbs
entrent dans la scope.
Devrais-je réécrire quelque chose?
def takesArray(arr: Array[AnyRef]) {…} def usesVarArgs(obs: AnyRef*) { takesArray(obs) }
doit devenir
def usesVarArgs(obs: AnyRef*) { takesArray(obs.toArray) }
J’ai dû visiter le canal IRC pour celui-là, mais j’ai alors réalisé que j’aurais dû commencer ici.
Voici une liste de contrôle d’Eric Willigers, qui utilise Scala depuis 2.2. Certains de ces éléments sembleront datés pour les utilisateurs plus récents.
* Importation explicite à partir de paquets externes *
Supposons que nous ayons
package a class B
Changement
package ac class D extends B
à
package ac import aB class D extends B
ou
package a package c class D extends B
* Utiliser un nom de package complet lors de l’importation depuis un package externe *
Supposons que nous ayons
package ab object O { val x = 1 }
Changement
package abc import bOx
à
package abc import abOx
* Lorsque vous spécifiez explicitement des parameters de type dans les appels de méthode de conteneur, ajoutez de nouveaux parameters de type *
Changement
list.map[Int](f)
à
list.map[Int, List[Int]](f)
Changement
map.transform[Value](g)
à
map.transform[Value, Map[Key, Value]](g)
* Créer une carte sortingée en utilisant la commande au lieu de la conversion en commande *
[scalac] found : (Ssortingng) => Ordered[Ssortingng] [scalac] required: Ordering[Ssortingng] [scalac] TreeMap[Ssortingng, Any](map.toList: _*)(ssortingngToCaseInsensitiveOrdered _)
* Importez les conversions implicites qui remplacent scala.collection.jcl *
* La carte immuable .update devient .updated *
*** Migrer à partir des méthodes List récemment obsolètes –
*elements
*remove
*sort
*List.flatten(someList)
*List.fromSsortingng(someList, sep)
*List.make
*** Utiliser les méthodes de liste *
diff
*iterator
*filterNot
*sortWith
*someList.flatten
*someList.split(sep)
*List.fill
* classpath lors de l’utilisation de scala.tools.nsc.Settings *
http://thread.gmane.org/gmane.comp.lang.scala/18245/focus=18247 settings.classpath.value = System.getProperty (“java.class.path”)
* Éviter l’erreur: _ doit suivre la méthode; ne peut pas suivre (Any) => Boolean *
Remplacer
list.filter(that.f _)
avec
list.filter(that f _)
ou
list.filter(that.f(_))
>>>
* Migration à partir des méthodes d’énumération obsolètes
map
* Utilisation des méthodes d’énumérationvalues.iterator
values.map
* Migrer à partir de
Iterator.fromValues(a, b, c, d)
obsolètesIterator.fromValues(a, b, c, d)
* UtiliserIterator(a, b, c, d)
* Evitez les types obsolètes
Collection
* Utilisez plutôtIterable
* Changer l’ordre d’initialisation *
Supposons que nous ayons
trait T { val v val w = v + v }
Remplacer
class C extends T { val v = "v" }
avec
class C extends { val v = "v" } with T
* Evitez les
val
inutilesfor (val x <- ...)
** Évitez les virgules *