let
- constant
var
-variable
[Constante vs variável]
[Estrutural vs Classe]
O documento oficial docs.swift.org diz
O valor de a constant
não pode ser alterado depois de definido, enquanto a variable
pode ser definido com um valor diferente no futuro.
Essa terminologia realmente descreve um mecanismo de reatribuição
Mutabilidade - mutável - o estado do objeto pode ser alterado após a criação
Valor e tipo de referência [Sobre]
Valor (Struct, Enum)
Os Swift struct
podem alterar seu status de mutabilidade:
let
+ struct
= immutable
= Constante de valor
Pode não ser reatribuído ou alterado
var
+ struct
= mutable
Pode ser reatribuído ou alterado
Tipo de referência (classe)
Swift's classes
são mutable
um priorado
let
+ class
= Constante de endereço
Ele pode não ser transferido e pode ser alterado
var
+ class
Pode ser reatribuído ou alterado
//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
- Funções de mutação do Struct
Você pode marcar o método de uma estrutura comomutating
- Indica que esta função altera os valores internos da propriedade.
- Só pode ser usado em
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
Modificando struct dentro de uma função
Você pode marcar o parâmetro de uma função (que é struct) como inout
Como struct
um tipo de valor, ele é passado por valor, pois a função de resultado recuperará uma cópia. Se você marcar um parâmetro struct
como inout
, significa que esse parâmetro se tornará var
e você poderá alterar um estado struct
e essas alterações serão visíveis fora do escopo da função
//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)
Use let
sempre que puder. Use var
quando você precisar.