是什么区别let,并var在苹果的雨燕语言?
根据我的理解,它是一种编译语言,但它不会在编译时检查类型.这让我感到困惑.编译器如何知道类型错误?如果编译器没有检查类型,那么生产环境是不是有问题?
jm6*_*666 397
的let关键字定义一个常数:
let theAnswer = 42
Run Code Online (Sandbox Code Playgroud)
在theAnswer无法改变之后.这就是为什么weak不能用任何东西写的原因let.他们需要在运行时更改,您必须使用它var.
在var定义了一个普通变量.
有趣的是:
在编译时不需要知道常量的值,但必须将该值分配一次.
另一个奇怪的功能
您可以使用几乎任何您喜欢的字符来表示常量和变量名称,包括Unicode字符:
let = "dogcow"
Run Code Online (Sandbox Code Playgroud)
节选自:Apple Inc."The Swift Programming Language."iBooks.https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewBook?id=881256329
因为评论要求在答案中添加其他事实,将其转换为社区维基答案.随意编辑答案,使其更好.
Krz*_*zak 32
根据The Swift Programming Language Book
与C一样,Swift使用变量来存储和通过标识名称引用值.Swift还广泛使用其值无法更改的变量.这些被称为常量,并且比C中的常量强大得多.
两个var和let是引用,因此let是一个常量引用.使用基本类型并没有真正显示出let与众不同的方式const.将它与类实例(引用类型)一起使用时会出现差异:
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"
Run Code Online (Sandbox Code Playgroud)
let- constant
var-variable
官方文档docs.swift.org说
a 的值
constant一旦设置就不能更改,而 avariable可以在将来设置为不同的值。
这个术语实际上描述了一种重新分配机制
可变性
Mutability - 可变 - 对象的状态可以在创建后改变[关于]
引用类型(类)
斯威夫特的classes是mutableA-修道院
var+class
可以重新分配或更改
let+ class=地址的常数
它可以不被重新分配,并且可以改变
值(结构,枚举)
Swiftstruct可以改变它们的可变性状态:
var+ struct=mutable
可以重新分配或更改
let+ struct= * 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"
}
}
Run Code Online (Sandbox Code Playgroud)
可能的用例
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
}
Run Code Online (Sandbox Code Playgroud)
mutating - 改变结构的功能您可以将结构的方法标记为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
}
Run Code Online (Sandbox Code Playgroud)
inout 在函数内部inout 允许您重新分配/修改传递的(原始)值。var在inout参数内部传递变量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
}
Run Code Online (Sandbox Code Playgroud)
*你偷是能够变异 let + struct
func testStructMutability() {
//given
let str: NSMutableString = "propertyClass"
let letMyStruct = MyStruct(str, "propertyStruct")
//when
str.append(" SECONDARY")
//then
XCTAssert(letMyStruct.letClass == "propertyClass SECONDARY")
}
Run Code Online (Sandbox Code Playgroud)
let尽可能使用。var必要时使用。
通过可变性/不可变性概念来表达这种差异可能更好,这是正确的范式和对象空间中的实例可变性,它大于唯一的"常数/变量"通常概念.此外,这更接近于Objective C方法.
2种数据类型:值类型和引用类型.
在价值类型的背景下:
'let'定义一个常量值(不可编码).'var'定义了一个可变的值(可变).
let aInt = 1 //< aInt is not changeable
var aInt = 1 //< aInt can be changed
Run Code Online (Sandbox Code Playgroud)
在参考类型的上下文中:
数据的标签不是值,而是对值的引用.
如果aPerson = Person(名字:Foo,第一名:Bar)
aPerson不包含此人的数据,但包含对此人数据的引用.
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)
Run Code Online (Sandbox Code Playgroud)
非常简单:
let 是不变的. var 是动态的.一点描述:
let创造一个常数.(有点像NSString).设置后,您无法更改其值.您仍然可以将其添加到其他内容并创建新变量.
var创建一个变量.(有点像NSMutableString)所以你可以改变它的价值.但这已得到多次回答.
let定义一个“常数”。它的值设置一次且仅一次,但不一定在您声明时设置。例如,您let用来定义必须在初始化期间设置的类中的属性:
class Person {
let firstName: String
let lastName: String
init(first: String, last: String) {
firstName = first
lastName = last
super.init()
}
}
Run Code Online (Sandbox Code Playgroud)
使用此设置,分配给firstName或lastName在调用(例如)之后Person(first:"Malcolm", last:"Reynolds")创建Person实例是无效的。
您必须在编译时为所有变量(let或var)定义一个类型,并且任何尝试设置变量的代码只能使用该类型(或子类型)。您可以在运行时分配值,但必须在编译时知道其类型。
| 归档时间: |
|
| 查看次数: |
164232 次 |
| 最近记录: |