Quelle est la différence entre «let» et «var» dans swift?


321

Quelle est la différence entre letet vardans le langage Swift d'Apple?

À ma connaissance, il s'agit d'un langage compilé mais il ne vérifie pas le type au moment de la compilation. Cela me rend confus. Comment le compilateur connaît-il l'erreur de type? Si le compilateur ne vérifie pas le type, n'est-ce pas un problème avec l'environnement de production?


35
let pour les constantes, var pour les variables.
Collin Henderson

2
@Edward Qu'entendez-vous par absence de vérification de type au moment de la compilation? Pour autant que je sache, il est typé statiquement, mais les types sont déduits si le compilateur peut le comprendre par lui-même. Mais alors je ne suis qu'à la page 25 ... ;-)
Joachim Isaksson

4
C'est sur le sujet mais une question mal formulée. Il y a au moins 2 questions (i) diff entre let et var ; (ii) inférence de type sûr vs type. De plus, lorsque l'affiche mentionnait l' étape de la production , il voulait vraiment dire au moment de l'exécution.
Kevin Le - Khnle

1
De plus, var utilisé sur les variables qui définissent les collections (tableaux et dictionnaire) crée une collection mutable (pas seulement la référence mais le contenu de la collection peut être modifié. L'autre utilisation de var est de pouvoir modifier les paramètres passés dans une fonction: func foo (var bar: Int) vous permettra de modifier localement la barre de param dans la portée de la fonction
Laurent

Réponses:


407

Le letmot-clé définit une constante:

let theAnswer = 42

Le theAnswerne peut pas être changé par la suite. C'est pourquoi rien weakne peut être écrit en utilisant let. Ils doivent changer pendant l'exécution et vous devez utiliser à la varplace.

Le vardéfinit une variable ordinaire.

Ce qui est intéressant:

La valeur d'une constante n'a pas besoin d'être connue au moment de la compilation , mais vous devez attribuer la valeur exactement une fois.

Une autre caractéristique étrange:

Vous pouvez utiliser presque tous les caractères que vous aimez pour les noms constants et variables, y compris les caractères Unicode:

let 🐶🐮 = "dogcow"

Extraits de: Apple Inc. «The Swift Programming Language». iBooks. https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewBook?id=881256329

ÉDITER

Parce que les commentaires demandent d'ajouter d'autres faits à la réponse, convertissant cela en réponse wiki communautaire . N'hésitez pas à modifier la réponse pour l'améliorer.


1
C et C ++ autorisent également les identificateurs Unicode, via les UCN. Si le compilateur prend en charge tout encodage source Unicode, vous pouvez simplement utiliser directement les caractères Unicode. Par exemple, auto 🐶🐮 = "dogcow";fonctionne en C ++ pour clang.
bames53

131
@ bames53 ok, je ne suis pas sûr que je veux déboguer un programme comme: if 😍 === 💝 { 💔 = ♠︎ }:);)
jm666

S'applique-t-il à REPL? Parce que vous pouvez réaffecter la constante dans REPL.
Ahmed Al Hafoudh

1
Tout d'abord, comme indiqué ci-dessus, cela est totalement différent dans le REPL. Deuxièmement, si c'est une constante, ce n'est pas beaucoup. Cela fonctionne très bien dans le compilateur: let foo = [1,2,3]; foo [2] = 5; println ("(foo)") // [1, 2, 5]
Kevin Frost

31
Cette réponse, bien que la plus votée, ne contient aucune mention du comportement de / var lors de la référence aux objets plutôt qu'aux types de valeur. La clé est que dans les deux cas, vous pouvez toujours modifier les propriétés de l'objet, mais ne pouvez pas modifier le pointeur pour faire référence à un autre objet. Ce n'est pas immédiatement évident à partir d'exemples de base impliquant des entiers et des chaînes.
SaltyNuts

33

Selon le livre du langage de programmation Swift

Comme C, Swift utilise des variables pour stocker et faire référence aux valeurs par un nom identifiant. Swift utilise également largement des variables dont les valeurs ne peuvent pas être modifiées. Celles-ci sont connues sous le nom de constantes et sont beaucoup plus puissantes que les constantes en C.

Les deux varet letsont des références , letest donc une référence const . L'utilisation de types fondamentaux ne montre pas vraiment en quoi letest différent de const. La différence vient de son utilisation avec des instances de classe (types de référence):

class CTest
{
    var str : String = ""
}

let letTest = CTest()
letTest.str = "test" // OK

letTest.str = "another test" // Still OK

//letTest = CTest() // Error

var varTest1 = CTest()
var varTest2 = CTest()
var varTest3 = CTest()

varTest1.str = "var 1"
varTest2.str = "var 2"
varTest3 = varTest1
varTest1.str = "var 3"

varTest3.str // "var 3"

1
Cette terminologie est totalement fausse ... Toutes les références sont en effet des références const. Il n'y a pas de concept de «const ref». Une fois liée, une référence est toujours liée à la même adresse mémoire et ne peut pas être modifiée ou "non assise". Je crois que vous voulez dire que var est un "pointeur" et que let est un "pointeur const"
AyBayBay

@AyBayBay Bien que ce que vous écrivez soit correct en C ++ par exemple, je pense que l'extrait ci-dessus prouve que ce n'est pas le cas dans Swift. Les pointeurs permettraient l'arithmétique des pointeurs et un accès direct à la mémoire, ce qui n'est pas le cas ici. - Edit: je n'ai trouvé aucune preuve que toutes les références sont en effet des références const est vrai pour tous les langages de programmation.
Krzak

BTW selon les pointeurs de Wikipédia sont des références
Krzak

2
J'accepte que votre terminologie soit erronée. varet letn'ont rien à voir avec le fait que l'identifiant lié soit ou non une référence. Si le type est un structtype, il s'agit conceptuellement d'une valeur. Si le type est un classc'est conceptuellement une référence et la référence est une constante si letest utilisée. Si CTestc'était une structure, aucune de vos letTestaffectations ne fonctionnerait.
JeremyP

1
Si le type est un structtype de valeur, il n'y a rien de conceptuel à ce sujet. Le même avec class- type de référence. Lorsque vous modifiez un type de valeur, vous créez une nouvelle instance de ce type. developer.apple.com/swift/blog/?id=10 Donc, évidemment, vous ne pouvez pas modifier les champs / propriétés letliés au type de valeur.
Krzak

15

letest utilisé pour définir des constantes et vardéfinir des variables.


7

Il est peut-être préférable d'énoncer cette différence par la notion de mutabilité / immutabilité qui est le paradigme correct des valeurs et de la variabilité des instances dans l'espace des objets qui est plus grande que les seules notions habituelles "constantes / variables". Et en plus c'est plus proche de l'approche Objectif C.

2 types de données: type de valeur et type de référence.

Dans le contexte des types de valeur:

'let' définit une valeur constante (indomptable). 'var' définit une valeur modifiable (mutable).

let aInt = 1   //< aInt is not changeable

var aInt = 1   //< aInt can be changed

Dans le contexte des types de référence:

L'étiquette d'une donnée n'est pas la valeur mais la référence à une valeur.

si aPerson = Person (nom: Foo, first: Bar)

aPerson ne contient pas les données de cette personne mais la référence aux données de cette personne.

let aPerson = Person(name:Foo, first:Bar)
               //< data of aPerson are changeable, not the reference

var aPerson = Person(name:Foo, first:Bar)
               //< both reference and data are changeable.

eg:
var aPersonA = Person(name:A, first: a)
var aPersonB = Person(name:B, first: b)

aPersonA = aPersonB

aPersonA now refers to Person(name:B, first: b)

1
mais si aPersona des setters vous pouvez modifier ses propriétés non? donc letça ne fait pas l' Personimmuable.
drewish

4
Immutabilité? C'est impossible! Certainement contre-conseillé. Je pense que votre mot que vous recherchez peut être "immuabilité" :-)
paxdiablo

6

le

La section Déclaration des constantes et variables de la documentation du langage de programmation Swift spécifie les éléments suivants:

Vous déclarez des constantes avec le mot clé let et des variables avec le mot clé var.

Assurez-vous de comprendre comment cela fonctionne pour les types de référence. Contrairement aux types de valeur, les propriétés sous-jacentes de l'objet peuvent changer malgré le fait qu'une instance d'un type de référence soit déclarée comme constante. Consultez la section Les classes sont des types de référence de la documentation et regardez l'exemple où elles modifient la propriété frameRate.


5

Très simple:

  • let est constant.
  • var est dynamique.

Un peu de description:

letcrée une constante. (un peu comme un NSString). Vous ne pouvez pas modifier sa valeur une fois que vous l'avez définie. Vous pouvez toujours l'ajouter à d'autres choses et créer de nouvelles variables.

varcrée une variable. (un peu comme NSMutableString) pour que vous puissiez en changer la valeur. Mais cela a été répondu plusieurs fois.


4

letdéfinit une "constante". Sa valeur est définie une seule fois, mais pas nécessairement lorsque vous la déclarez. Par exemple, vous utilisez letpour définir une propriété dans une classe qui doit être définie lors de l'initialisation:

class Person {

    let firstName: String
    let lastName: String

    init(first: String, last: String) {
         firstName = first
         lastName = last
         super.init()
    }
}

Avec cette configuration, il n'est pas valide de l'attribuer à firstNameou lastNameaprès avoir appelé (par exemple) Person(first:"Malcolm", last:"Reynolds")pour créer une Personinstance.

Vous devez définir un type pour toutes les variables ( letou var) au moment de la compilation, et tout code qui tente de définir une variable ne peut utiliser que ce type (ou un sous-type). Vous pouvez affecter une valeur au moment de l'exécution, mais son type doit être connu au moment de la compilation.


4

let- constant
var-variable

[Constante vs variable]
[Struct vs classe]

Le doc officiel docs.swift.org dit

La valeur de a constantne peut pas être modifiée une fois définie, tandis que a variablepeut être définie sur une valeur différente à l'avenir.

Cette terminologie décrit en fait un mécanisme de réaffectation

Mutabilité - modifiable - l'état de l'objet peut être modifié après sa création

Valeur et type de référence [À propos]

Valeur (Struct, Enum)

Les Swift structpeuvent changer leur statut de mutabilité:

let+ struct= immutable= constante de valeur
Elle ne peut pas être réaffectée ou modifiée

var+ struct= mutable
Il peut être réaffecté ou modifié

Type de référence (classe)

Les Swift classessont mutableun prieuré

let+ class= constante d'adresse
Elle ne peut pas être réaffectée et peut être modifiée

var+ class
Il peut être réaffecté ou modifié

//STRUCT
  //let + struct
let letStructA = StructA()

    //change FAIL
letStructA.a = 5 //Compile ERROR: Cannot assign to property: 'structALet' is a 'let' constant

    //reassign FAIL
letStructA = StructA() // Compile ERROR: Cannot assign to value: 'structALet' is a 'let' constant

  //var + struct
var varStructA = StructA()

    //change OK
varStructA.a = 5

    //reassign OK
varStructA = StructA()

//CLASS
  //let + class
let letClassA = ClassA()

    //change OK
letClassA.a = 5

    //reassign FAIL
letClassA = ClassA() // Compile ERROR: Cannot assign to value: 'classALet' is a 'let' constant

  //var + class
var varClassA = ClassA()

    //change OK
varClassA.a = 5

    //reassign OK
varClassA = ClassA()

mutating - Fonctions de Structures Mutantes

Vous pouvez marquer la méthode d' une structure commemutating

  1. Indique que cette fonction modifie les valeurs des propriétés internes.
  2. Ne peut être utilisé que sur var+struct
public struct StructA {
    public var a = 0

    public init() {}

    //func foo() { //Compile ERROR: Cannot assign to property: 'self' is immutable
    mutating func foo() {
        a = 5
    }
}

inout Modification de la structure à l'intérieur d'une fonction

Vous pouvez marquer le paramètre d'une fonction (qui est struct) comme inout

Depuis structun type de valeur, il est passé par valeur car une fonction de résultat récupérera une copie. Si vous marquez un paramètre en structtant que inout, cela signifie que ce paramètre devient varet vous pouvez modifier un état de structet ces modifications seront visibles en dehors de la portée de la fonction

//func foo(myStruct: StructA) { //Compile ERROR: line - myStruct.a = 10: Cannot assign to property: 's' is a 'let' constant
func foo(myStruct: inout StructA) {
    myStruct.a = 10
}

//using
//foo(myStruct: &letStructA) // Compile EROOR: Cannot pass immutable value as inout argument: 'letStructA' is a 'let' constant
foo(myStruct: &varStructA)

Utilisez letquand vous le pouvez. Utilisez varquand vous le devez.


2

Une autre différence, que j'ai rencontrée dans d'autres langages pour les constantes, est: ne peut pas initialiser la constante (let) pour plus tard , devrait s'initialiser lorsque vous êtes sur le point de déclarer la constante.

Par exemple :

let constantValue : Int // Compile error - let declarations require an initialiser expression

Variable

var variableValue : Int // No issues 

2

letest utilisé pour déclarer une valeur constante - vous ne la modifierez pas après lui avoir donné une valeur initiale.
varest utilisé pour déclarer une valeur variable - vous pouvez changer sa valeur comme vous le souhaitez.


1

let est utilisé pour définir des constantes et var pour définir des variables. Vous définissez la chaîne à l'aide de var, une chaîne particulière peut être modifiée (ou mutée) en l'affectant à une variable (auquel cas elle peut être modifiée), et si vous définissez la chaîne à l'aide de laissez sa constante (auquel cas elle ne peut pas être modifié):

var variableString = "Apple"
variableString += " and Banana"
// variableString is now "Apple and Banana"

let constantString = "Apple"
constantString += " and another Banana"
// this reports a compile-time error - a constant string cannot be modified

0

let mot clé définit une constante

let myNum = 7

donc myNum ne peut pas être modifié par la suite;

Mais var définit une variable ordinaire.

La valeur d'une constante n'a pas besoin d'être connue au moment de la compilation, mais vous devez lui affecter une valeur exactement une fois.

Vous pouvez utiliser presque tous les caractères que vous aimez pour les noms constants et variables, y compris les caractères Unicode;

par exemple

var x = 7 // here x is instantiated with 7 
x = 99 // now x is 99 it means it has been changed.

Mais si nous prenons alors laisser ...

let x = 7 // here also x is instantiated with 7 
x = 99 // this will a compile time error

0

Comme Luc-Oliver, NullData et quelques autres l'ont dit ici, letdéfinit les données immuables tout en vardéfinissant les données mutables. Tout ce funcqui peut être appelé sur la variable qui est marquée mutatingne peut être appelé que s'il s'agit d'une varvariable (le compilateur générera une erreur). Cela vaut également pour ceux funcqui prennent une inoutvariable.

Cependant, letet varsignifie aussi que la variable ne peut être réaffecté. Il a deux significations, toutes deux à des fins très similaires


0

La valeur var peut être modifiée après l'initialisation. Mais que la valeur ne change pas, lorsqu'elle est intilisée une fois.

En cas de var

  function variable() {
     var number = 5, number = 6;
     console.log(number); // return console value is 6
   }
   variable();

En cas de location

   function abc() {
      let number = 5, number = 6;
      console.log(number); // TypeError: redeclaration of let number
   }
   abc();

Mais que la valeur ne change pas, lorsqu'elle est intilisée une fois. Je ne suis pas d'accord avec ça. Votre commentaire est très bien avec des valeurs non objet comme int, float. Mais essayez avec un tableau et une chaîne mutables, vous pouvez modifier leurs valeurs en ajoutant ou en ajoutant des valeurs. Le correct est de laisser les objets ne peuvent pas être modifiés par son pointeur leur adresse de pointeur sera toujours la même raison pour laquelle vous obtenez une erreur de réinitialisation. Vous pouvez donc dire que let fait un pointeur const qui ne peut pas être changé à l'avenir.
TheTiger

Il n'y a pas de console.log dans Swift. Vérifiez l'étiquette du PO
Dan Beaulieu

0

Le mot-clé var est utilisé pour définir une variable dont vous pouvez facilement changer la valeur comme ceci:

var no1 = 1 // declaring the variable 
no1 = 2 // changing the value since it is defined as a variable not a constant

Cependant, le mot clé let sert uniquement à créer une constante utilisée lorsque vous ne souhaitez pas modifier à nouveau la valeur de la constante. Si vous essayez de changer la valeur de la constante, vous obtiendrez une erreur:

let no2 = 5 // declaring no2 as a constant
no2 = 8 // this will give an error as you cannot change the value of a constant 

0

Let est une variable immuable, ce qui signifie qu'elle ne peut pas être modifiée, d'autres langages l'appellent une constante. En C ++, vous pouvez le définir comme const.

Var est une variable mutable, ce qui signifie qu'elle peut être modifiée. En C ++ (mise à jour de la version 2011), c'est la même chose que d'utiliser auto, bien que swift permette plus de flexibilité dans l'utilisation. Il s'agit du type de variable le plus connu des débutants.


0

let est une valeur constante, elle ne peut donc jamais être modifiée.

let number = 5  
number = 6               //This will not compile.

Var est une variable et peut changer (mais une fois définie, elle ne doit pas être utilisée avec un type de données différent.)

var number = 5
number = 6               //This will compile.

Si vous essayez de changer la variable en un autre type de données, cela ne fonctionnera pas

var number = 5
number = "Hello World"   //This will not compile.

1
Laissez devrait être laissé .
TheTiger

0

La principale différence est que la varvaleur de la variable peut changer et letne peut pas. Si vous souhaitez avoir des données d'entrée utilisateur, vous devez utiliser varpour que la valeur puisse être modifiée et utiliser une letvariable de type de données pour que la valeur ne puisse pas être modifiée.

var str      = "dog"  // str value is "dog"
str          = "cat"  // str value is now "cat"

let strAnimal = "dog" // strAnimal value is "dog"
strAnimal     = "cat" // Error !

Let and Var ne fonctionne pas en utilisant (let et var) en minuscule.
Abhishek

0

Une valeur peut être réaffectée en cas de var

 //Variables
 var age = 42
 println(age) //Will print 42
 age = 90
 println(age) //Will Print 90

** la constante newAge ne peut pas être réaffectée à une nouvelle valeur. Essayer de le faire donnera une erreur de temps de compilation **

//Constants
let newAge = 92 //Declaring a constant using let
println(newAge) //Will print 92.


0

var est variable qui peut être modifiée autant de fois que vous le souhaitez et à chaque fois

par exemple

var changeit:Int=1
changeit=2
 //changeit has changed to 2 

laisse constant qui ne peut pas être changé

par exemple

let changeit:Int=1
changeit=2
 //Error becuase constant cannot be changed

0

Même si vous avez déjà beaucoup de différence entre let et var, mais une différence principale est:

let is compiled fast in comparison to var.

-1

Tout le monde a à peu près répondu à cette question, mais voici un moyen de vous souvenir de ce que

Laissons toujours dire la même chose de "let" car laissez cela fonctionner pour une fois et toujours comme pour les variables "var" qui peuvent toujours changer d'où qu'elles soient appelées variables


-1

varest le seul moyen de créer une variable en swift. varne signifie pas variable dynamique comme dans le cas de langages interprétés comme javascript. Par exemple,

var name = "Bob"

Dans ce cas, le type de variable nameest déduit que le nom est de type String, nous pouvons également créer des variables en définissant explicitement le type, par exemple

var age:Int = 20

Maintenant, si vous affectez une chaîne à l'âge, le compilateur donne l'erreur.

letest utilisé pour déclarer des constantes. Par exemple

let city = "Kathmandu"

Ou nous pouvons aussi faire,

let city:String = "Kathmandu"

Si vous essayez de changer la valeur de city, cela donne une erreur au moment de la compilation.


-1

let est utilisé pour les constantes qui ne peuvent pas être modifiées alors que var est une variable ordinaire

Exemple:

let name = "Bob" Quelque chose comme name = "Jim" générera une erreur car une constante ne peut pas être modifiée.


-1

DIFFÉRENCE SIMPLE

let = (ne peut pas être modifié)

var = (mise à jour à tout moment)


1
Cela semble être juste une répétition de nombreuses réponses existantes.
Pang

-1

Source: https://thenucleargeeks.com/2019/04/10/swift-let-vs-var/

Lorsque vous déclarez une variable avec var, cela signifie qu'elle peut être mise à jour, elle est variable, sa valeur peut être modifiée.

Lorsque vous déclarez une variable avec let, cela signifie qu'elle ne peut pas être mise à jour, elle n'est pas variable, sa valeur ne peut pas être modifiée.

var a = 1 
print (a) // output 1
a = 2
print (a) // output 2

let b = 4
print (b) // output 4
b = 5 // error "Cannot assign to value: 'b' is a 'let' constant"

Comprenons l'exemple ci-dessus: Nous avons créé une nouvelle variable «a» avec «mot-clé var» et attribué la valeur «1». Lorsque j'imprime «a», j'obtiens la sortie 1. Puis j'affecte 2 à «var a», c'est-à-dire que je modifie la valeur de la variable «a». Je peux le faire sans obtenir d'erreur de compilation car je l'ai déclaré comme var.

Dans le deuxième scénario, j'ai créé une nouvelle variable «b» avec «let mot-clé» et affecté la valeur «4». Lorsque j'imprime «b», j'en ai obtenu 4 en sortie. Ensuite, j'essaie d'attribuer 5 à «let b», c'est-à-dire que j'essaie de modifier la variable «let» et j'obtiens une erreur de temps de compilation «Impossible d'attribuer à la valeur:« b »est une constante« let »».


-3

Bien qu'actuellement je lise toujours le manuel, mais je pense que c'est très proche du constpointeur C / C ++ . En d'autres termes, quelque chose comme la différence entre char const*et char*. Le compilateur refuse également de mettre à jour le contenu, pas seulement la réassignation de référence (pointeur).

Par exemple, supposons que vous ayez cette structure. Veillez à ce que ce soit une structure, pas une classe. AFAIK, les classes n'ont pas de concept d'état immuable.

import Foundation


struct
AAA
{
    var inner_value1    =   111

    mutating func
    mutatingMethod1()
    {
        inner_value1    =   222
    }
}


let aaa1    =   AAA()
aaa1.mutatingMethod1()      // compile error
aaa1.inner_value1 = 444     // compile error

var aaa2    =   AAA()
aaa2.mutatingMethod1()      // OK
aaa2.inner_value1 = 444     // OK

Comme les structures sont immuables par défaut, vous devez marquer une méthode de mutation avec mutating. Et parce que le nom aaa1est constant, vous ne pouvez pas appeler de méthode de mutation dessus. C'est exactement ce que nous attendions sur les pointeurs C / C ++.

Je crois que c'est un mécanisme pour supporter une sorte de substance de const-correct .


-3

Déclarez les constantes avec le mot clé let et les variables avec le mot clé var.

let maximumNumberOfLoginAttempts = 10 var currentLoginAttempt = 0   
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0

Déclarez plusieurs constantes ou plusieurs variables sur une seule ligne, séparées par des virgules:

var x = 0.0, y = 0.0, z = 0.0

Impression des constantes et des variables

Vous pouvez imprimer la valeur actuelle d'une constante ou d'une variable avec la fonction println:

println(friendlyWelcome)

Swift utilise l'interpolation de chaîne pour inclure le nom d'une constante ou d'une variable comme espace réservé dans une chaîne plus longue

Mettez le nom entre parenthèses et échappez-le avec une barre oblique inverse avant la parenthèse d'ouverture:

println("The current value of friendlyWelcome is \(friendlyWelcome)")

Référence: http://iosswift.com.au/?p=17


-4

J'ai trouvé une bonne réponse, j'espère que cela peut aider :) entrez la description de l'image ici


4
C'est en fait incorrect. letne signifie pas que l' objet est immuable, cela signifie que le pointeur est immuable. Pour obtenir la fonctionnalité équivalente dans Obj-C, vous devez utiliser NSObject *const myObject = someobject;- Les propriétés de cet objet peuvent être modifiées, mais le pointeur myObjectne peut pas être modifié pour pointer vers un autre objet.
SaltyNuts

1
Réponse totalement fausse. Avez-vous essayé avec un tableau let: NSMutableArray = NSMutableArray () ?? Vous pouvez ajouter et supprimer des objets à / de cela. laissez des marques const pointerqui ne peuvent pas être modifiées à l'avenir, mais sa valeur peut l'être. Vous ne pouvez pas le réinitialiser mais vous pouvez l'utiliser comme vous le souhaitez.
TheTiger
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.