58 votes

Quelles sont les plus grandes différences entre les Scala 2.8 et Scala 2.7?

J'ai écrit un assez grand programme dans la Scala 2.7.5, et maintenant, je suis impatient de la version 2.8. Mais je suis curieux de savoir comment ce grand saut dans l'évolution de la Scala va m'affecter.

Ce sera la plus grande des différences entre ces deux versions de la Scala? Et peut-être le plus important:

  • Vais-je avoir besoin de réécrire quelque chose?
  • Puis-je envie de réécrire quelque chose juste pour profiter de nouvelles fonctionnalités géniales?
  • Justement, quelles sont les nouvelles fonctionnalités de la Scala 2.8 en général?

37voto

retronym Points 35066

Faire le Saut

Lors de la migration, le compilateur peut vous fournir des filets de sécurité.

  1. Compiler votre ancien code contre 2.7.7 avec -deprecation, et suivez les les recommandations de tous les autodérision mises en garde.
  2. Mise à jour de votre code pour utiliser unnnested paquets. Cela peut être fait mécaniquement par l'exécution répétée de cette expression régulière remplacer.

    s/^(package com.example.project.*)\.(\w+)/$1\npackage $2/g
    
  3. Compiler avec 2.8.0 compilateur, à l'aide de paranoïaque options de ligne de commande -deprecation -Xmigration -Xcheckinit -Xstrict-warnings -Xwarninit

  4. Si vous recevez des erreurs l'erreur could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T], vous devez ajouter un paramètre implicite (ou de manière équivalente, un contexte lié), sur un paramètre de type.

    Avant:

    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                                              ^
    

    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 lui-même prend T comme un paramètre de type, doit également accepter le Manifeste comme un paramètre implicite. Voir les Tableaux de SID pour plus de détails.

  5. Avant trop longtemps, vous rencontrerez une erreur comme ceci:

    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]
                 ^
    

    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é Map -- lecture seule interface: collection.Map, est immuable de mise en œuvre: collection.immutable.Map, et une mutable mise en œuvre: collection.mutable.Map. En outre, la bibliothèque définit le comportement d'un ensemble parallèle de traits MapLike, mais c'est vraiment un détail d'implémentation.

Récolter les Bénéfices

  1. Remplacer certains surcharge de la méthode avec des nommés et des paramètres par défaut.
  2. Utiliser le générés copy méthode de classes de cas.

      scala> case class Foo(a: Int, b: String)
      defined class Foo
    
    
      scala> Foo(1, "a").copy(b = "b")
      res1: Foo = Foo(1,b)
    
  3. Généraliser vos signatures de méthode de List de Seq ou Iterable ou Traversable. Parce que les classes de collection sont dans un état propre à la hiérarchie, pouvez-vous accepter un type plus général.
  4. Intégrer avec les bibliothèques Java à l'aide d'Annotations. Vous pouvez maintenant spécifier imbriqués les annotations, et d'avoir un contrôle précis quant à savoir si les annotations sont ciblées sur des champs ou de méthodes. Cela permet d'utiliser le Printemps ou JPA avec Scala code.

Il existe de nombreuses autres fonctionnalités qui peuvent être ignorés en toute sécurité que vous commencez à la migration, par exemple @specialized et les Suites.

33voto

VonC Points 414372

Vous pouvez trouver ici un aperçu de la nouvelle fonctionnalité de Scala2.8 (avril 2009), complété avec récente de cet article (juin 2009)

  • Nommé et Arguments par Défaut
  • Imbriqués Les Annotations
  • Les Objets De Package
  • @spécialisés
  • L'amélioration de Collections (certains de réécriture peut être nécessaire ici)
  • REPL aura achèvement de commande (plus sur cela et d'autres astuces dans cet article)
  • De nouvelles Abstractions de Contrôle (poursuite ou la pause)
  • Les améliorations (Swing wrapper, spectacles, ...)

"La réécriture de code" n'est pas une obligation (sauf pour l'utilisation de certains de l'amélioration de Collections), mais certaines fonctionnalités comme la continuation (Wikipédia: une représentation abstraite de l'état de contrôle, ou le "reste" de calcul" ou "repos de l'exécution d'un code") peut vous donner quelques nouvelles idées. Une bonne introduction est trouvé ici, écrit par Daniel (qui a également affiché un beaucoup plus détaillée et plus précise de réponse dans ce fil).

Remarque: Scala sur Netbeans semble fonctionner avec certains 2.8 nuit-build (vs la page officielle de 2.7.x)

25voto

Daniel C. Sobral Points 159554

VonC la réponse est difficile d'améliorer, donc je ne vais même pas essayer. Je vais couvrir certains d'autres choses ne sont pas mentionnés par lui.

Tout d'abord, certains obsolète choses vont aller. Si vous avez la dépréciation des avertissements dans votre code, il est probable qu'il ne compile pas plus.

Ensuite, Scala, à la bibliothèque est en cours d'extension. Pour la plupart, peu commun à des motifs tels que la capture des exceptions en Either ou Option, ou de la conversion d'un AnyRef en Option avec null mappé en None. Ces choses peuvent passer inaperçus, mais je suis fatigué de poster quelque chose sur le blog et, plus tard, d'avoir quelqu'un me dire qu'il est déjà sur Scala 2.8. Eh bien, en fait, je ne suis pas fatigué , mais, plutôt, et heureusement, l'habitude. Et je ne parle pas ici sur les Collections, qui sont l'obtention d'une révision majeure.

Maintenant, il serait bien si les gens posté des exemples concrets de telles améliorations apportées à la bibliothèque que de réponses. Je serais heureux de upvote toutes ces réponses.

REPL n'est pas juste de commande d'achèvement. Il se fait beaucoup de choses, y compris la capacité d'examiner les AST pour un objet, ou la possibilité d'insérer des points d'arrêt dans le code qui tombent dans REPL.

Aussi, Scala compilateur est modifié pour être en mesure de fournir rapidement partielle de la compilation, de IDEs, ce qui signifie que nous pouvons nous attendre à devenir beaucoup plus "compétent" à propos de la Scala -- par l'interrogation de la Scala compilateur lui-même sur le code.

Un grand changement est susceptible de passer inaperçu par beaucoup, mais il va diminuer les problèmes de la bibliothèque des écrivains et des utilisateurs. Maintenant, si vous écrivez le texte suivant:

package com.mystuff.java.wrappers

import java.net._

Vous importez pas de Java net bibliothèque, mais com.mystuff.javas' net bibliothèque, com, com.mystuff, com.mystuff.java et com.mystuff.java.wrappers tous eu au sein de la portée, et java peut être trouvé à l'intérieur d' com.mystuff. Avec Scala 2.8, seulement wrappers obtient étendue. Depuis, parfois, vous voulez un peu de repos pour être Portée, une alternative package syntaxe est permis:

package com.mystuff.factories
package ligthbulbs

ce qui est équivalent à:

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

Et arrive à obtenir à la fois factories et lightbulbs dans l'étendue.

11voto

Bart Schuller Points 1992

Vais-je avoir besoin de 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 eu à visiter le canal IRC pour que l'on, mais alors réalisé que j'aurais du commencer ici.

6voto

Daniel C. Sobral Points 159554

Voici une liste de Eric Willigers, qui a été à l'aide de la Scala depuis la 2.2. Certaines de ces choses semblent datés de plus les utilisateurs récents.

* Explicitement importer à partir de l'extérieur des paquets *

Supposons que nous avons

package a
class B

Changement

package a.c
class D extends B

pour

package a.c
import a.B
class D extends B

ou

package a
package c
class D extends B

* Utiliser pleinement qualifié du nom du package lors de l'importation à partir de l'emballage extérieur *

Supposons que nous avons

package a.b
object O { val x = 1 }

Changement

package a.b.c
import b.O.x

pour

package a.b.c
import a.b.O.x

* Lors de spécifier explicitement les paramètres de type de conteneur des appels de méthode, d'ajouter de nouveaux paramètres de type *

Changement

list.map[Int](f)

pour

list.map[Int, List[Int]](f)

Changement

map.transform[Value](g)

pour

map.transform[Value, Map[Key, Value]](g)

* Créer triés carte à l'aide de la Commande à la place de conversion pour Ordonnées *

 [scalac]  found   : (String) => Ordered[String]
 [scalac]  required: Ordering[String]
 [scalac]         TreeMap[String, Any](map.toList: _*)(stringToCaseInsensitiveOrdered _)

* Importer les conversions implicites qui remplacent scala.collection.jcl *

* Immuable De La Carte .mise à jour devient .mise à jour *

* Migrer viennent d'être obsolète Liste des méthodes --
* elements * remove * sort * List.flatten(someList) * List.fromString(someList, sep) * List.make

* Utilisation de la Liste des méthodes * diff * iterator * filterNot * sortWith * someList.flatten * someList.split(sep) * List.fill

* classpath lors de l'utilisation de scala.outils.nsc.Réglages *

http://thread.gmane.org/gmane.comp.lang.scala/18245/focus=18247 les paramètres.classpath.valeur = Système.getProperty("java.classe.chemin d'accès")

* Éviter l'erreur: _ devez suivre la méthode; ne peut pas suivre (Tout) => Boolean *

Remplacer

list.filter(that.f _)

avec

list.filter(that f _)

ou

list.filter(that.f(_))

> > >

* Migrer à partir obsolète Énumération des méthodes d' iterator map * L'utilisation de l'Énumération des méthodes d' values.iterator values.map

* Migrer à partir obsolète Iterator.fromValues(a, b, c, d) * Utiliser Iterator(a, b, c, d)

* Éviter obsolète type Collection * Utiliser Iterable au lieu

* Changement de l'initialisation de la commande *

Supposons que nous avons

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

* Éviter d'inutiles val en for (val x <- ...) *

* Éviter les virgules *

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X