67 votes

Ce sont toutes les instances de sucre syntaxique dans Scala?

Ce sont toutes les instances de sucre syntaxique dans Scala?

Ils sont durs à la recherche pour puisque la plupart d'entre eux sont purement symboles et sont donc difficiles à rechercher sans connaître le nom de ce concept.

TODO:

  • Les conversions implicites
  • _ de la syntaxe pour les fonctions anonymes
  • D'autres choses que j'oublie

63voto

Jackson Davis Points 1518

Notions de base:

  • a b est équivalent à a.b
  • a b c est équivalent à a.b(c), sauf lorsqu' b se termine en :. Dans ce cas, a b c est équivalent à c.b(a)
  • a(b) est équivalent à a.apply(b) C'est pourquoi les définitions suivantes pour les fonctions anonymes sont identiques: val square1 = (x: Int) => x*x val square2 = new Fonction1[Int,Int] { def appliquer(x: Int) = x*x }

Lors de l'appel d' square1(y), vous êtes en fait en appelant square1.apply(y) qui square1 doit être spécifié par l' Function1 trait (ou Function2, etc...)

  • a(b) = c est équivalent à a.update(b,c) de Même, a(b,c) = d est équivalent à a.update(b,c,d) et ainsi de suite.
  • a.b = c est équivalent à a.b_=(c). Lorsque vous créez un val/var x dans une Classe/Objet, Scala crée les méthodes d' x et x_= pour vous. Vous pouvez définir vous-même, mais si vous définissez y_= vous devez définir y ou il ne compile pas, par exemple,

    scala> val b = new Object{ def set_=(a: Int) = println(a) }
    b: java.lang.Object{def set_=(Int): Unit} = $anon$1@17e4cec
    
    scala> b.set = 5
    <console>:6: error: value set is not a member of java.lang.Object{def set_=(Int): Unit}
           b.set = 5
             ^
    
    scala> val c = new Object{ def set = 0 ; def set_=(a:Int) = println(a) }
    c: java.lang.Object{def set: Int; def set_=(Int): Unit} = $anon$1@95a253
    
    scala> c.set = 5
    5
    
  • -a correspond a.unary_- de Même pour +a,~a, et !a

  • a <operator>= b<operator> est un ensemble de caractères spéciaux, est équivalent à a = a <operator> b seulement si l' a n'ont pas l' <operator>= méthode, par exemple,

    class test(val x:Int) {
        def %%(y: Int) = new test(x*y)
    }
    
    var a = new test(10)
    a.x // 10
    a %%= 5 //Equivalent to a = a %% 5
    a.x // 50
    

21voto

Jackson Davis Points 1518

Des Classes spéciales: les Tuples et les Symboles

Comme mentionné par Rahul G, les tuples et les symboles obtenir un peu spécial de la syntaxe.

  • Symboles: la syntaxe 'x "est l'abréviation de Symbol("x")
  • Les Tuples: (p1,p2,..,pn) est court pour une classe de cas Tuplen[T1,T2,..,Tn](p1,p2,..,pn)

Par exemple, les deux suivantes sont équivalentes.

val tuple1 = ("Hello",1)
val tuple2 = Tuple2[String,Int]("Hello",1)

19voto

IttayD Points 10490

En plus de Jaxkson de réponse:

  • type F[A,B] peut être utilisé comme A F B.

Par exemple:

type ->[A,B] = (A,B)
def foo(f: String -> String)
  • À l'aide de => type dans une définition de méthode rend le compilateur envelopper les expressions à l'intérieur de l'appel de la méthode en fonction de thunk.

Par exemple

def until(cond: => Boolean)(body: => Unit) = while(!cond) body

var a = 0
until (a > 5) {a += 1}

15voto

Jackson Davis Points 1518

Les extracteurs:

Il existe deux méthodes utilisées pour les extracteurs, unapply et unapplySeq. Ces produits sont utilisés dans de multiples affectations de variables et le pattern matching.

  • Le premier cas d'utilisation est l'endroit où délettrer prend l'objet qu'elle est censée correspondre et renvoie un Boolean basée sur si oui ou non elle correspond, par exemple,

    trait Gender
    trait Male extends Gender
    trait Female extends Gender
    object Male extends Male
    object Female extends Female
    class Person(val g: Gender, val age: Int)
    
    object Adult {
        def unapply(p: Person) = p.age >= 18
    }
    
    def check(p: Person) = p match {
        case Adult() => println("An Adult")
        case _ => println("A Child")
    }
    
    //Will print: An Adult since Adult.unapply returns true.
    check(new Person(Female, 18))
    
    //Will print: A Child as it falls through to the _ case.
    check(new Person(Male, 17))
    

Honnêtement, je n'ai pas vraiment le but de la syntaxe ci-dessus, car il peut être fait à peu près aussi facilement simplement en mettant le code dans l' case des déclarations. Bien sûr, si vous avez un meilleur exemple, laisser un commentaire ci-dessous

  • Le cas général où la unapply prend un peu de fixe-nombre de paramètres et retourne soit une Option[T] pour un seul paramètre ou un Option[(p1,p2,...)] pour plusieurs, c'est à dire un Tuple avec les paires de valeurs, par exemple, continue de le code ci-dessus:

    object Person {
        def apply(g: Gender, age: Int) = new Person(g, age)
        def unapply(p: Person) = if(p.age < 0) None else Some((p.g, p.age))
    }
    
    //Using Person.apply as described in the Basics section
    val alice = Person(Female, 30)
    val bob = Person(Male, 25)
    
    //This calls Person.unapply(alice), which returns Some((Female, 30)).
    //alice_gender is assigned Female and alice_age 30.
    val Person(alice_gender, alice_age) = alice
    
    bob match {
        //Calls Person.unapply(bob), but sees that g is Male, so no match.
        case Person(Female, _) => println("Hello ma'am")
        //Calls Person.unapply(bob) and assigns age = bob.age, but it doesn't pass
        //the 'if' statement, so it doesn't match here either.
        case Person(Male, age) if age < 18 => println("Hey dude")
        //So bob falls through to here
        case _ => println("Hello Sir")
    }
    
    Person(Male,-1) match {
        //Person.unapply(Person.apply(Male,-1)) returns None because p.age < 0.
        //Therefore this case will not match.
        case Person(_, _) => println("Hello person")
        //Thus it falls through to here.
        case _ => println("Are you Human?")
    }
    

Remarque: Cas des classes et de tous ceux apply/unapply définitions pour vous (ainsi que d'autres trucs) afin de les utiliser whenver possible de gagner du temps et réduire le code.

  • unapplySeq. Cela fonctionne de la même manière à l' unapply comme ci-dessus, sauf qu'il doit retourner un Option d'une sorte de séquence.

Comme un exemple rapide,

scala> List.unapplySeq(List(1,2,3))
res2: Some[List[Int]] = Some(List(1, 2, 3))

7voto

Erik Allik Points 9158

Contexte limites desugar en implicit paramètres, par exemple, considérer une fonction qui tire parti de l' Monoid type de classe:

def suml[T: Monoid](xs: List[T]) = {
  val T = implicitly[Monoid[T]]
  xs.foldLeft(T.mzero)(T.mplus)
}

où l' : Monoid partie est un contexte lié, se traduit en:

def suml[T](xs: List[T])(implicit evidence$1: Monoid[T]]) = {
  ...
}

par conséquent la suivante compile, trop:

def suml[T: Monoid](xs: List[T]) = {
  val T = evidence$1
  ...
}

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