Qual è la differenza tra `let` e` var` in swift?


321

Qual è la differenza tra lete varnel linguaggio Swift di Apple?

A mio avviso, è un linguaggio compilato ma non controlla il tipo al momento della compilazione. Mi rende confuso. Come fa il compilatore a sapere dell'errore di tipo? Se il compilatore non controlla il tipo, non è un problema con l'ambiente di produzione?


35
let è per le costanti, var è per le variabili.
Collin Henderson,

2
@Edward Cosa intendi con nessun controllo del tipo in fase di compilazione? Per quanto posso dire, è tipizzato staticamente, ma i tipi vengono dedotti se il compilatore può capirlo da solo. Ma poi sono solo a pagina 25 ... ;-)
Joachim Isaksson,

4
Questo è un argomento, ma una domanda mal formulata. Ci sono almeno 2 domande (i) diff tra let e var ; (ii) digitare safe vs type infer. Inoltre, quando il poster parlava della fase di produzione , intendeva davvero in fase di esecuzione.
Kevin Le - Khnle l'

1
Inoltre, var utilizzato su variabili che definiscono raccolte (matrici e dizionario) crea una raccolta mutabile (non solo il riferimento ma il contenuto della raccolta può essere modificato. L'altro utilizzo di var è la possibilità di modificare i parametri passati in una funzione: func foo (var bar: Int) ti permetterà di modificare la barra dei parametri localmente nell'ambito della funzione
Laurent,

Risposte:


407

La letparola chiave definisce una costante:

let theAnswer = 42

La theAnswernon può essere modificato in seguito. Questo è il motivo per cui nulla weakpuò essere scritto usando let. Devono cambiare durante il runtime e devi varinvece utilizzare .

La vardefinisce una variabile ordinaria.

Ciò che è interessante:

Non è necessario conoscere il valore di una costante al momento della compilazione , ma è necessario assegnare il valore esattamente una volta.

Un'altra strana caratteristica:

Puoi usare quasi tutti i caratteri che ti piacciono per nomi costanti e variabili, inclusi i caratteri Unicode:

let 🐶🐮 = "dogcow"

Estratti da: Apple Inc. "The Swift Programming Language". iBook. https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewBook?id=881256329

MODIFICARE

Perché i commenti chiedono di aggiungere altri fatti alla risposta, convertendoli in una risposta wiki della comunità . Sentiti libero modifica la risposta per migliorarla.


1
C e C ++ consentono anche identificatori Unicode, tramite UCN. Se il compilatore supporta qualsiasi codifica sorgente Unicode, puoi semplicemente utilizzare direttamente i caratteri Unicode. Ad esempio auto 🐶🐮 = "dogcow";funziona in C ++ per clang.
bames53,

131
@ bames53 ok, non sono sicuro di voler eseguire il debug di un programma del tipo: if 😍 === 💝 { 💔 = ♠︎ }:);)
jm666

Si applica a REPL? Perché è possibile riassegnare la costante in REPL.
Ahmed Al Hafoudh,

1
Innanzitutto, come notato sopra, questo è totalmente diverso nel REPL. Secondo, se è una costante non è granché. Funziona bene nel compilatore: let foo = [1,2,3]; foo [2] = 5; println ("(foo)") // [1, 2, 5]
Kevin Frost,

31
Questa risposta, sebbene la più votata, non ha alcuna menzione di come si comportano let / var quando si fa riferimento a oggetti anziché a tipi di valore. La chiave è che in entrambi i casi è ancora possibile modificare le proprietà dell'oggetto, ma non è possibile modificare il puntatore per fare riferimento a un altro oggetto. Ciò non è immediatamente evidente dagli esempi di base che coinvolgono numeri interi e stringhe.
SaltyNuts,

33

Secondo il Swift Programming Language Book

Come C, Swift utilizza le variabili per memorizzare e fare riferimento ai valori con un nome identificativo. Swift fa inoltre ampio uso di variabili i cui valori non possono essere modificati. Queste sono conosciute come costanti e sono molto più potenti delle costanti in C.

Entrambi vare letsono riferimenti , quindi letè un riferimento const . L'uso di tipi fondamentali non mostra davvero quanto letsia diverso da const. La differenza si presenta quando lo si utilizza con istanze di classe (tipi di riferimento):

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
Questa terminologia è totalmente sbagliata ... Tutti i riferimenti sono effettivamente riferimenti costanti. Non esiste un concetto di "const const". Una volta associato, un riferimento è sempre associato allo stesso indirizzo di memoria e non può essere modificato o "non posizionato". Credo che tu
voglia

@AyBayBay Mentre quello che stai scrivendo è corretto, ad es. In C ++, penso che lo snippet di cui sopra dimostri che non è il caso di Swift. I puntatori consentirebbero l'aritmetica del puntatore e l'accesso diretto alla memoria, il che non è ancora il caso. - Modifica: non ho trovato prove che tutti i riferimenti siano effettivamente riferimenti costanti è vero per ogni linguaggio di programmazione.
Krzak,

BTW secondo i puntatori di Wikipedia sono riferimenti
Krzak,

2
Sono d'accordo che la tua terminologia sia errata. vare letnon hanno nulla a che fare con il fatto che l'identificatore associato sia o meno un riferimento. Se il tipo è un structtipo, è concettualmente un valore. Se il tipo è a classè concettualmente un riferimento e il riferimento è una costante se letviene utilizzato. Se CTestfosse una struttura, nessuno dei tuoi letTestcompiti avrebbe funzionato.
JeremyP,

1
Se il tipo è un structtipo di valore, non c'è nulla di concettuale al riguardo. Lo stesso con class- tipo di riferimento. Quando modifichi un tipo di valore, crei una nuova istanza di questo tipo. developer.apple.com/swift/blog/?id=10 Quindi ovviamente non è possibile modificare campi / proprietà letassociati al tipo di valore.
Krzak,

15

letè usato per definire costanti e varper definire variabili.


7

Forse è meglio affermare questa differenza con la nozione di mutabilità / immutabilità che è il paradigma corretto di valori e modificabilità delle istanze nello spazio Oggetti che è più grande delle uniche nozioni "costanti / variabili". Inoltre, ciò è più vicino all'approccio dell'obiettivo C.

2 tipi di dati: tipo di valore e tipo di riferimento.

Nel contesto dei tipi di valore:

'let' definisce un valore costante (indomabile). 'var' definisce un valore modificabile (mutabile).

let aInt = 1   //< aInt is not changeable

var aInt = 1   //< aInt can be changed

Nel contesto dei tipi di riferimento:

L'etichetta di un dato non è il valore ma il riferimento a un valore.

if aPerson = Person (nome: Foo, primo: Bar)

aPerson non contiene i dati di questa persona ma il riferimento ai dati di questa persona.

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
ma se aPersonha setter potresti modificarne le proprietà giusto? quindi il letnon rende l' Personimmutabile.
Drewish

4
Unmutability? È impossibile! Certamente antiadvisibile. Penso che la tua parola che stai cercando possa essere "immutabilità" :-)
paxdiablo

6

Il

La sezione Dichiarazioni di costanti e variabili della documentazione del linguaggio di programmazione Swift specifica quanto segue:

Dichiarate le costanti con la parola chiave let e le variabili con la parola chiave var.

Assicurati di capire come funziona per i tipi di riferimento. A differenza dei tipi di valore, le proprietà sottostanti dell'oggetto possono cambiare nonostante un'istanza di un tipo di riferimento venga dichiarata come costante. Vedi la sezione Classi sono tipi di riferimento della documentazione e guarda l'esempio in cui cambiano la proprietà frameRate.


5

Molto semplice:

  • let è costante
  • var è dinamico.

Bit di descrizione:

letcrea una costante. (un po 'come un NSString). Non è possibile modificarne il valore dopo averlo impostato. Puoi comunque aggiungerlo ad altre cose e creare nuove variabili però.

varcrea una variabile. (una specie di like NSMutableString) in modo da poterne modificare il valore. Ma questo è stato risposto più volte.


4

letdefinisce una "costante". Il suo valore è impostato una volta e una sola volta, anche se non necessariamente quando lo dichiari. Ad esempio, si utilizza letper definire una proprietà in una classe che deve essere impostata durante l'inizializzazione:

class Person {

    let firstName: String
    let lastName: String

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

Con questa configurazione, non è possibile assegnare firstNameo lastNamedopo aver chiamato (ad es.) Person(first:"Malcolm", last:"Reynolds")Per creare Personun'istanza.

È necessario definire un tipo per tutte le variabili ( leto var) al momento della compilazione e qualsiasi codice che tenti di impostare una variabile può utilizzare solo quel tipo (o un sottotipo). È possibile assegnare un valore in fase di esecuzione, ma il suo tipo deve essere noto in fase di compilazione.


4

let- constant
var-variable

[Costante vs variabile]
[Struct vs Class]

Dice doc ufficiale docs.swift.org

Il valore di a constantnon può essere modificato una volta impostato, mentre a variablepuò essere impostato su un valore diverso in futuro.

Questa terminologia in realtà descrive un meccanismo di riassegnazione

Mutabilità - modificabile - lo stato dell'oggetto può essere modificato dopo la creazione

Valore e tipo di riferimento [Informazioni]

Valore (Struct, Enum)

Gli Swift structpossono cambiare il loro stato di mutabilità:

let+ struct= immutable= Costante di valore
Può non essere riassegnato o modificato

var+ struct= mutable
Può essere riassegnato o modificato

Tipo di riferimento (classe)

Gli Swift classessono mutableun priorato

let+ class= Costante di indirizzo
Può non essere riassegnato e può essere cambiato

var+ class
Può essere riassegnato o modificato

//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 - Funzioni mutanti di Struct

È possibile contrassegnare il metodo di struct comemutating

  1. Indica che questa funzione modifica i valori delle proprietà interne.
  2. Può essere utilizzato solo su 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 Modifica di una struttura all'interno di una funzione

È possibile contrassegnare il parametro di una funzione (che è struct) come inout

Dal momento che structun tipo di valore, viene passato per valore poiché una funzione risultante recupererà una copia. Se si contrassegna un parametro structcome inoutsignifica che questo parametro diventa vare si è in grado di cambiare uno stato di structe queste modifiche saranno visibili al di fuori dell'ambito della funzione

//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)

Usa letquando puoi. Utilizzare varquando è necessario.


2

Un'altra differenza, che ho riscontrato in altre lingue per Costanti è: impossibile inizializzare la costante (let) per dopo , dovrebbe inizializzarsi mentre state per dichiarare la costante.

Per esempio :

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

Variabile

var variableValue : Int // No issues 

2

letè usato per dichiarare un valore costante - non lo cambierai dopo avergli dato un valore iniziale.
varviene utilizzato per dichiarare un valore variabile: è possibile modificarlo come si desidera.


1

let è usato per definire costanti e var per definire variabili. Definisci la stringa usando var quindi una particolare stringa può essere modificata (o mutata) assegnandola a una variabile (nel qual caso può essere modificata), e se definisci la stringa usando lascia che sia una costante (nel qual caso non può essere modificato):

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

lascia che la parola chiave definisca una costante

let myNum = 7

quindi myNum non può essere modificato in seguito;

Ma var definisce una variabile ordinaria.

Non è necessario conoscere il valore di una costante al momento della compilazione, ma è necessario assegnarlo esattamente una volta.

Puoi usare quasi tutti i caratteri che ti piacciono per nomi costanti e variabili, inclusi i caratteri Unicode;

per esempio

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

Ma se prendiamo lascia quindi ...

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

0

Come Luc-Oliver, NullData e alcuni altri hanno già detto qui, letdefinisce i dati immutabili mentre vardefinisce i dati mutabili. Tutto funcciò che può essere chiamato sulla variabile contrassegnata mutatingpuò essere chiamato solo se si tratta di una varvariabile (il compilatore genererà un errore). Questo vale anche per quelli funcche contengono uninout variabile.

Tuttavia, lete varsignifica anche che la variabile non può essere riassegnata. Ha due significati, entrambi con scopi molto simili


0

il valore var può essere modificato, dopo l'inizializzazione. Ma lascia che il valore non sia un cambiamento, quando viene intilizzato una volta.

In caso di var

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

In caso di let

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

Ma lascia che il valore non sia un cambiamento, quando viene intilizzato una volta. Non sono d'accordo con questo. Il tuo commento va bene con valori non oggetto come int, float. Ma prova con un array mutabile e una stringa mutabile, puoi modificarne i valori aggiungendo o aggiungendo valori. Il corretto è lasciare che gli oggetti non possano essere cambiati dal suo puntatore, il loro indirizzo del puntatore sarà sempre lo stesso, per questo motivo si riceve un errore di reinizializzazione. Quindi puoi dire che lascia puntatore const che non può essere cambiato in futuro.
TheTiger

Non c'è console.log in Swift. Controlla il tag dell'OP
Dan Beaulieu

0

La parola chiave var viene utilizzata per definire una variabile il cui valore può essere facilmente modificato in questo modo:

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

Tuttavia, la parola chiave let è solo per creare una costante utilizzata quando non si desidera modificare nuovamente il valore della costante. Se dovessi provare a modificare il valore della costante, visualizzerai un errore:

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 è una variabile immutabile, nel senso che non può essere modificata, altre lingue la chiamano costante. In C ++ puoi definirlo come const.

Var è una variabile mutabile, il che significa che può essere modificata. In C ++ (aggiornamento della versione 2011), è uguale all'utilizzo di auto, sebbene swift consenta una maggiore flessibilità nell'uso. Questo è il tipo di variabile più noto ai principianti.


0

let è un valore costante, quindi non può mai essere modificato.

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

Var è una variabile e può cambiare (ma dopo che è stato definito non in un diverso tipo di dati.)

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

Se si tenta di modificare la variabile in un tipo di dati diverso, non funzionerà

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

1
Let dovrebbe essere lasciato .
TheTiger

0

La differenza principale è che il varvalore della variabile può cambiare e letnon può. Se si desidera che un utente inserisca i dati, è necessario utilizzarlo in varmodo che il valore possa essere modificato e utilizzare la letvariabile tipo di dati in modo che il valore non possa essere modificato.

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 e ​​Var non funziona usando (let e var) in lettere minuscole.
Abhishek,

0

Un valore può essere riassegnato in caso di var

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

** la costante newAge non può essere riassegnata a un nuovo valore. Provare a farlo darà un errore di tempo di compilazione **

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


0

var è una variabile che può essere cambiata quante volte vuoi e ogni volta

per esempio

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

let è costante che non può essere modificato

per esempio

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

0

Anche se hai già molte differenze tra let e var, ma una differenza principale è:

let is compiled fast in comparison to var.

-1

Tutti hanno praticamente risposto a questa domanda, ma ecco un modo per ricordare cosa è cosa

Let dirà sempre lo stesso pensa a "let" in quanto lascia che funzioni una volta e sempre come per le variabili "var" possono sempre cambiare, quindi vengono chiamate variabili


-1

varè l'unico modo per creare rapidamente una variabile. varnon significa variabile dinamica come nel caso di linguaggi interpretati come javascript. Per esempio,

var name = "Bob"

In questo caso, namesi deduce il tipo di variabile che il nome è di tipoString , possiamo anche creare variabili definendo esplicitamente il tipo, ad esempio

var age:Int = 20

Ora se assegni una stringa all'età, allora il compilatore dà l'errore.

letè usato per dichiarare le costanti. Per esempio

let city = "Kathmandu"

Oppure possiamo anche fare,

let city:String = "Kathmandu"

Se si tenta di modificare il valore di città, viene visualizzato un errore al momento della compilazione.


-1

let è usato per le costanti che non possono essere modificate mentre var è una variabile ordinaria

Esempio:

let name = "Bob" Qualcosa come name = "Jim" genererà un errore poiché una costante non può essere modificata.


-1

DIFFERENZA SEMPLICE

let = (non può essere modificato)

var = (in qualsiasi momento aggiornamento)


1
Questo sembra essere solo una ripetizione di molte delle risposte esistenti.
Pang

-1

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

Quando dichiari una variabile con var, significa che può essere aggiornata, è variabile, il suo valore può essere modificato.

Quando dichiari una variabile con let, significa che non può essere aggiornata, non è variabile, il suo valore non può essere modificato.

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"

Comprendiamo l'esempio sopra: abbiamo creato una nuova variabile "a" con "var keyword" e assegnato il valore "1". Quando stampo "a" ottengo un output come 1. Quindi assegno 2 a "var a", ovvero sto modificando il valore della variabile "a". Posso farlo senza ottenere l'errore del compilatore perché l'ho dichiarato come var.

Nel secondo scenario ho creato una nuova variabile "b" con "let keyword" e assegnato il valore "4". Quando stampo "b" ho ottenuto 4 come output. Quindi provo ad assegnare 5 a "let b", cioè sto cercando di modificare la variabile "let" e ottengo un errore di compilazione "Impossibile assegnare al valore: 'b' è una costante 'let'.


-3

Anche se attualmente sto ancora leggendo il manuale, ma penso che questo sia molto vicino al constpuntatore C / C ++ . In altre parole, qualcosa come la differenza tra char const*e char*. Il compilatore rifiuta anche di aggiornare il contenuto, non solo la riassegnazione di riferimento (puntatore).

Ad esempio, supponiamo che tu abbia questa struttura. Fai attenzione che questa è una struttura, non una classe. AFAIK, le classi non hanno un concetto di stato immutabile.

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

Poiché le strutture sono immutabili per impostazione predefinita, è necessario contrassegnare un metodo mutatore con mutating. E poiché il nome aaa1è costante, non è possibile chiamare alcun metodo mutatore su di esso. Questo è esattamente ciò che ci aspettavamo dai puntatori C / C ++.

Credo che questo sia un meccanismo per supportare una sorta di roba di correttezza const .


-3

Dichiarare le costanti con la parola chiave let e le variabili con la parola chiave var.

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

Dichiarare più costanti o più variabili su una sola riga, separate da virgole:

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

Costanti e variabili di stampa

È possibile stampare il valore corrente di una costante o variabile con la funzione println:

println(friendlyWelcome)

Swift utilizza l'interpolazione di stringhe per includere il nome di una costante o variabile come segnaposto in una stringa più lunga

Avvolgere il nome tra parentesi e sfuggirlo con una barra rovesciata prima della parentesi di apertura:

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

Riferimento: http://iosswift.com.au/?p=17


-4

Trovato una buona risposta spero che possa aiutare :) inserisci qui la descrizione dell'immagine


4
Questo non è corretto. letnon significa che l' oggetto è immutabile, significa che il puntatore è immutabile. Per ottenere la funzionalità equivalente in Obj-C è necessario utilizzare NSObject *const myObject = someobject;- Le proprietà di tale oggetto possono essere modificate, ma il puntatore myObjectnon può essere modificato per puntare a un altro oggetto.
SaltyNuts,

1
Risposta totalmente sbagliata. Hai provato con un array let: NSMutableArray = NSMutableArray () ?? È possibile aggiungere e rimuovere oggetti da / per questo. lascia che ciò const pointerche non può essere cambiato in futuro, ma il suo valore può essere. Non puoi reinizializzarlo ma puoi usarlo come vuoi.
TheTiger
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.