在苹果的Swift语言中,let和var有什么区别?
在我的理解中,它是一种编译语言,但它不在编译时检查类型。这让我很困惑。编译器如何知道类型错误?如果编译器不检查类型,这不是生产环境的问题吗?
当我试图给let赋值时给出了这个错误:
不能给属性赋值:'variableName'是一个'let'常量 将'let'改为'var'使其可变
在苹果的Swift语言中,let和var有什么区别?
在我的理解中,它是一种编译语言,但它不在编译时检查类型。这让我很困惑。编译器如何知道类型错误?如果编译器不检查类型,这不是生产环境的问题吗?
当我试图给let赋值时给出了这个错误:
不能给属性赋值:'variableName'是一个'let'常量 将'let'改为'var'使其可变
当前回答
非常简单:
设为常数。 Var是动态的。
描述一下:
创建一个常数。(有点像NSString)。一旦你设置了它,你就不能改变它的值。你仍然可以把它添加到其他东西,并创建新的变量。
Var创建一个变量。(有点像NSMutableString)所以你可以改变它的值。但这个问题已经被回答了好几次。
其他回答
关键字var用来定义一个变量,你可以像这样轻松地修改它的值:
var no1 = 1 // declaring the variable
no1 = 2 // changing the value since it is defined as a variable not a constant
但是,let关键字仅用于创建一个常量,当您不想再次更改常量的值时使用。如果你试图改变常数的值,你会得到一个错误:
let no2 = 5 // declaring no2 as a constant
no2 = 8 // this will give an error as you cannot change the value of a constant
来源:https://thenucleargeeks.com/2019/04/10/swift-let-vs-var/
当你用var声明一个变量时,这意味着它可以被更新,它是一个变量,它的值可以被修改。
当你用let声明一个变量时,这意味着它不能被更新,它是非变量,它的值不能被修改。
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"
让我们理解上面的例子:我们已经创建了一个新变量“a”,带有“var关键字”,并赋值为“1”。当我输出“a”时,输出结果为1。然后我给“var a”赋值2,即我正在修改变量“a”的值。这样做不会引起编译器错误,因为我声明为var。
在第二个场景中,我用“let关键字”创建了一个新变量“b”,并赋值为“4”。当我输出b时,我得到4作为输出。然后我尝试将5分配给“let b”,即我试图修改“let”变量,我得到编译时错误“不能分配给值:' b '是一个' let '常量”。
在var的情况下,值可以被重新赋值
//Variables
var age = 42
println(age) //Will print 42
age = 90
println(age) //Will Print 90
** newAge常量不能被重新赋给一个新值。尝试这样做会给出一个编译时错误**
//Constants
let newAge = 92 //Declaring a constant using let
println(newAge) //Will print 92.
Swift let和var
Let -常数 Var -变量
[常量vs变量] [结构vs类]
官方文件docs.swift.org说
常量的值一旦设置就不能更改,而变量可以在将来设置为不同的值。
这个术语实际上描述了一种重新分配机制
可变性
可变性-可更改-对象创建后状态可以更改[关于]
取值及参考类型[关于]
引用类型(类)
Swift的类是可变的
Var +类 它可以被重新分配或更改
Let + class =地址常数 它不能被重新分配,可以被更改
值(结构、枚举)
Swift的struct可以改变它们的可变性状态:
Var + struct =可变的 它可以被重新分配或更改
let + struct = *immutable或unmodifiable[关于][示例][示例]= value的常量 它不能被重新分配或更改
*immutable检查testStructMutability测试
实验:
class MyClass {
var varClass: NSMutableString
var varStruct: String
let letClass: NSMutableString
let letStruct: String
init(_ c: NSMutableString, _ s: String) {
varClass = c
varStruct = s
letClass = c
letStruct = s
}
}
struct MyStruct {
var varClass: NSMutableString
var varStruct: String
let letClass: NSMutableString
let letStruct: String
init(_ c: NSMutableString, _ s: String) {
varClass = c
varStruct = s
letClass = c
letStruct = s
}
//mutating function block
func function() {
// varClass = "SECONDARY propertyClass" //Cannot assign to property: 'self' is immutable
// varStruct = "SECONDARY propertyStruct" //Cannot assign to property: 'self' is immutable
}
mutating func mutatingFunction() {
varClass = "SECONDARY propertyClass"
varStruct = "SECONDARY propertyStruct"
}
}
可能的用例
func functionVarLetClassStruct() {
var varMyClass = MyClass("propertyClass", "propertyStruct")
varMyClass.varClass = "SECONDARY propertyClass"
varMyClass.varStruct = "SECONDARY propertyStruct"
// varMyClass.letClass = "SECONDARY propertyClass" //Cannot assign to property: 'letClass' is a 'let' constant
// varMyClass.letStruct = "SECONDARY propertyStruct" //Cannot assign to property: 'letStruct' is a 'let' constant
let letMyClass = MyClass("propertyClass", "propertyStruct")
letMyClass.varClass = "SECONDARY propertyClass"
letMyClass.varStruct = "SECONDARY propertyStruct"
// letMyClass.letClass = "SECONDARY propertyClass" //Cannot assign to property: 'letClass' is a 'let' constant
// letMyClass.letStruct = "SECONDARY propertyStruct" //Cannot assign to property: 'letStruct' is a 'let' constant
var varMyStruct = MyStruct("propertyClass", "propertyStruct")
varMyStruct.varClass = "SECONDARY propertyClass"
varMyStruct.varStruct = "SECONDARY propertyStruct"
// varMyStruct.letClass = "SECONDARY propertyClass" //Cannot assign to property: 'letClass' is a 'let' constant
// varMyStruct.letStruct = "SECONDARY propertyStruct" //Cannot assign to property: 'letStruct' is a 'let' constant
let letMyStruct = MyStruct("propertyClass", "propertyStruct")
// letMyStruct.varClass = "SECONDARY propertyClass" //Cannot assign to property: 'letMyStruct' is a 'let' constant
// letMyStruct.varStruct = "SECONDARY propertyStruct" //Cannot assign to property: 'letMyStruct' is a 'let' constant
// letMyStruct.letClass = "SECONDARY propertyClass" //Cannot assign to property: 'letClass' is a 'let' constant
// letMyStruct.letStruct = "SECONDARY propertyStruct" //Cannot assign to property: 'letStruct' is a 'let' constant
}
mutating -改变结构的函数
可以将结构的方法标记为突变
指示此函数更改内部属性值 你只能在var变量上调用变异函数 当突变函数完成时,结果可见
func testStructMutatingFunc() {
//given
var varMyStruct = MyStruct("propertyClass", "propertyStruct")
//when
varMyStruct.mutatingFunction()
//than
XCTAssert(varMyStruct.varClass == "SECONDARY propertyClass" && varMyStruct.varStruct == "SECONDARY propertyStruct")
// It is not possible to call a mutating function on a let variable
let letMyStruct = MyStruct("propertyClass", "propertyStruct")
// letMyStruct.mutatingFunction() //Cannot use mutating member on immutable value: 'letMyStruct' is a 'let' constant
}
函数内的Inout
Inout允许您重新分配/修改传递的(原始)值。 你只能在inout参数内传递var变量 当功能完成时,结果可见
Inout有一个下一个流程:
传递的值在函数调用之前被复制到被复制的值中 复制的值在函数完成后被赋值为传递的值
//InOut
func functionWithInOutParameter(a: inout MyClass, s: inout MyStruct) {
a = MyClass("SECONDARY propertyClass", "SECONDARY propertyStruct") //<-- assign
s = MyStruct("SECONDARY propertyClass", "SECONDARY propertyStruct") //<-- assign
}
func testInOutParameter() {
//given
var varMyClass = MyClass("PRIMARY propertyClass", "PRIMARY propertyStruct")
var varMyStruct = MyStruct("PRIMARY propertyClass", "PRIMARY propertyStruct")
//when
functionWithInOutParameter(a: &varMyClass, s: &varMyStruct)
//then
XCTAssert(varMyClass.varClass == "SECONDARY propertyClass" && varMyClass.varStruct == "SECONDARY propertyStruct")
XCTAssert(varMyStruct.varClass == "SECONDARY propertyClass" && varMyStruct.varStruct == "SECONDARY propertyStruct")
// It is not possible to pass let into inout parameter
let letMyClass = MyClass("PRIMARY propertyClass", "PRIMARY propertyStruct")
let letMyStruct = MyStruct("PRIMARY propertyClass", "PRIMARY propertyStruct")
// functionWithInOutParameter(a: &letMyClass, s: &letMyStruct) //Cannot pass immutable value as inout argument: 'letMyClass', 'letMyStruct' are 'let' constants
}
*你偷可以改变let + struct
func testStructMutability() {
//given
let str: NSMutableString = "propertyClass"
let letMyStruct = MyStruct(str, "propertyStruct")
//when
str.append(" SECONDARY")
//then
XCTAssert(letMyStruct.letClass == "propertyClass SECONDARY")
}
尽可能使用let。必要时使用var。
(变异结构)
Let关键字定义一个常量
let myNum = 7
所以myNum之后不能更改;
但是var定义了一个普通变量。
常量的值不需要在编译时知道,但是必须为它赋值一次。
你可以使用几乎任何你喜欢的字符作为常量和变量名,包括Unicode字符;
e.g.
var x = 7 // here x is instantiated with 7
x = 99 // now x is 99 it means it has been changed.
但是如果我们采取let,那么……
let x = 7 // here also x is instantiated with 7
x = 99 // this will a compile time error