153 votes

Utilisation de def, val et var en scala

class Person(val name:String,var age:Int )
def person = new Person("Kumar",12)
person.age = 20
println(person.age)

Ces lignes de code sorties 12, même si person.age=20 a été exécutée avec succès. J'ai trouvé que cela se passe parce que j'ai utilisé def en def person = new Person("Kumar",12). Si j'utilise la var ou val la sortie est 20. Je comprends la valeur par défaut est de val en scala. Ce:

def age = 30
age = 45

...donne une erreur de compilation car c'est un val par défaut. Pourquoi le premier ensemble de lignes au-dessus de ne pas fonctionner correctement, et pourtant ne font pas d'erreur?

243voto

Jesper Points 65733

Il y a trois façons de définir les choses en Scala:

  • def définit une méthode
  • val définit un fixe de la valeur (qui ne peut pas être modifié)
  • var définit une variable (qui peut être modifié)

En regardant ton code:

def person = new Person("Kumar",12)

Ceci définit une nouvelle méthode appelée person. Vous pouvez appeler cette méthode que sans - () , car elle est définie comme une méthode sans paramètre. Pour le vide-parenthèse méthode, vous pouvez l'appeler avec ou sans '()'. Si vous écrivez simplement:

person

ensuite, vous êtes à l'appel de cette méthode (et si vous n'avez pas affecter la valeur de retour, il va juste être jeté). Dans cette ligne de code:

person.age = 20

ce qui se passe est que vous devez d'abord appeler l' person méthode, et sur la valeur de retour (une instance de la classe Person) d'avoir à changer l' age variable membre.

Et la dernière ligne:

println(person.age)

Ici, vous êtes à nouveau l'appel de la person méthode, qui renvoie une nouvelle instance de la classe Person (avec age ensemble de 12). C'est la même chose comme ceci:

println(person().age)

29voto

Kintaro Points 912

Avec

def person = new Person("Kumar", 12) 

vous êtes à la définition d'une fonction/paresseux variable qui renvoie toujours une nouvelle instance de Personne avec le nom "Kumar" et de l'âge de 12 ans. C'est tout à fait valide et le compilateur n'a aucune raison de se plaindre. L'appel de la personne.l'âge sera de retour l'âge de cette Personne nouvellement créés exemple, qui est toujours de 12.

Lors de l'écriture

person.age = 45

vous pouvez affecter une nouvelle valeur à l'âge de propriété dans la classe Personne, ce qui est valable depuis l'âge de est déclarée var. Le compilateur va se plaindre si vous vous essayez à réaffecter person avec une nouvelle Personne comme objet

person = new Person("Steve", 13)  // Error

25voto

AnonJ Points 127

Pour offrir un autre point de vue, "def" dans Scala signifie quelque chose qui va être évalués à chaque fois quand il est utilisé, tandis que val est quelque chose qui est évalué immédiatement et en une seule fois. Ici, l'expression def person = new Person("Kumar",12) implique que chaque fois que nous utilisons "personne", nous aurons une new Person("Kumar",12) appel. Par conséquent, il est naturel que les deux "personne.âge" sont non-liées.

C'est la façon dont je le comprends Scala(probablement plus "fonctionnelle"). Je ne suis pas sûr si

def defines a method
val defines a fixed value (which cannot be modified)
var defines a variable (which can be modified)

c'est vraiment ce que Scala a l'intention de dire. Je n'aime pas vraiment que penser de cette façon au moins...

20voto

Landei Points 30509

Comme Kintaro déjà dit, la personne est une méthode (à cause de def) et toujours retourne une nouvelle instance de Personne. Comme vous l'avez découvert que cela fonctionnerait si vous modifiez la méthode de la var ou val:

val person = new Person("Kumar",12)

Une autre possibilité serait:

def person = new Person("Kumar",12)
val p = person
p.age=20
println(p.age)

Toutefois, person.age=20 dans votre code est autorisé, ce que vous obtenez en retour un Person de la person méthode, et sur ce cas, vous êtes autorisé à modifier la valeur d'un var. Le problème est, qu'après que ligne vous n'avez plus de référence à cette instance (comme à chaque appel à l' person va produire une nouvelle instance).

Ce n'est rien de spécial, on aurait exactement le même comportement en Java:

class Person{ 
   public int age; 
   private String name;
   public Person(String name; int age) {
      this.name = name;  
      this.age = age;
   }
   public String name(){ return name; }
}

public Person person() { 
  return new Person("Kumar", 12); 
}

person().age = 20;
System.out.println(person().age); //--> 12

8voto

Daniel C. Sobral Points 159554

Prenons ceci :

et le réécrire avec code équivalent

Voir, est une méthode. Il s’exécute chaque fois qu’elle est appelée, et chaque fois qu’elle sera de retour (un) . Et ce n’est aucune erreur dans le « affectation » parce qu’il n’est pas vraiment une cession, mais simplement un appel à la méthode (fournis par ).

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