let
和var
Apple的Swift语言有什么区别?
以我的理解,它是一种编译语言,但它不会在编译时检查类型。这让我感到困惑。编译器如何知道类型错误?如果编译器不检查类型,那么生产环境是否存在问题?
let
和var
Apple的Swift语言有什么区别?
以我的理解,它是一种编译语言,但它不会在编译时检查类型。这让我感到困惑。编译器如何知道类型错误?如果编译器不检查类型,那么生产环境是否存在问题?
Answers:
的let
关键字定义一个常数:
let theAnswer = 42
在theAnswer
无法改变之后。这就是为什么weak
不能使用编写任何内容的原因let
。它们需要在运行时进行更改,而您必须在使用它们var
。
在var
定义了一个普通变量。
有趣的是:
常量的值不需要在编译时就知道,但是您必须精确地分配一次值。
另一个奇怪的功能:
对于常量和变量名称,几乎可以使用任何喜欢的字符,包括Unicode字符:
let 🐶🐮 = "dogcow"
摘自:Apple Inc.“ Swift编程语言”。iBooks。https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewBook?id=881256329
因为评论要求在答案中添加其他事实,所以将其转换为社区Wiki答案。随意编辑答案以使其更好。
auto 🐶🐮 = "dogcow";
在C ++中适用于clang。
if 😍 === 💝 { 💔 = ♠︎ }
);)
根据《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"
var
与let
绑定的标识符是否为引用无关。如果类型是struct
类型,则从概念上讲是值。如果类型是a class
,则从概念上讲是一个引用,如果let
使用,则引用是一个常量。如果CTest
是一个结构体,那么您的任何letTest
分配都不会起作用。
struct
值类型,则没有任何概念上的意义。与class
-引用类型相同。修改值类型时,将创建此类型的新实例。developer.apple.com/swift/blog/?id=10因此,显然您不能修改let
绑定到值类型的字段/属性。
最好通过“可变性/不可更改性”概念来说明这种差异,该概念是“对象”空间中值和实例可变性的正确范例,比唯一的“常数/变量”常规概念更大。而且,这更接近于Objective C方法。
2种数据类型:值类型和引用类型。
在值类型的上下文中:
“ let”定义一个恒定值(不可调整)。“ var”定义一个可变值(可变)。
let aInt = 1 //< aInt is not changeable
var aInt = 1 //< aInt can be changed
在引用类型的上下文中:
数据的标签不是值,而是对值的引用。
如果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)
aPerson
有设置员,您可以修改其属性吗?所以let
不会使Person
不可变的。
很简单:
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()
}
}
使用此设置,在调用(例如)创建实例时分配firstName
或分配给实例是无效的。lastName
Person(first:"Malcolm", last:"Reynolds")
Person
您必须在编译时为所有变量(let
或var
)定义一种类型,任何试图设置变量的代码都只能使用该类型(或子类型)。您可以在运行时分配一个值,但是在编译时必须知道其类型。
let
- constant
var
-variable
官方文件docs.swift.org说
a的值一经设置
constant
就无法更改,而variable
将来可以将其设置为其他值。
该术语实际上描述了重新分配机制
可变性-可更改-创建后可以更改对象的状态
值(结构,枚举)
Swift struct
可以更改其可变性状态:
let
+ struct
= immutable
= 的值恒定
它可以不被重新分配或改变
var
+ struct
= mutable
可以重新分配或更改
参考类型(类)
斯威夫特的classes
是mutable
A-修道院
let
+ class
= 地址的常数
它可以不被重新分配,并且可以改变
var
+ class
可以重新分配或更改
//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
-改变结构的功能您可以将结构的方法标记为mutating
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
在函数内部修改结构您可以将函数的参数(结构)标记为 inout
由于struct
是值类型,因此按值传递它,因为结果函数将检索副本。如果将a标记struct
为inout
参数,则表示此参数变为,var
并且您可以更改其状态,struct
并且这些更改将在功能范围之外可见
//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)
let
尽可能使用。var
必要时使用。
let用于定义常量,而 var用于定义变量。您可以定义使用字符串 VAR然后特定字串可以通过将其分配给一个变量(在这种情况下,可以修改)被修改(或突变),如果你定义字符串使用让它是一个常数(在这种情况下,不能改性):
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
let关键字定义一个常量
let myNum = 7
因此,之后无法更改myNum;
但是var定义了一个普通变量。
常量的值在编译时不需要知道,但是您必须为它赋值一次。
常量和变量名几乎可以使用任何您喜欢的字符,包括Unicode字符。
例如
var x = 7 // here x is instantiated with 7
x = 99 // now x is 99 it means it has been changed.
但是,如果我们采取让...
let x = 7 // here also x is instantiated with 7
x = 99 // this will a compile time error
初始化后,可以更改var值。但是让价值一旦被利用就不会改变。
如果是var
function variable() {
var number = 5, number = 6;
console.log(number); // return console value is 6
}
variable();
如果让
function abc() {
let number = 5, number = 6;
console.log(number); // TypeError: redeclaration of let number
}
abc();
关键字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
let是一个恒定值,因此永远无法更改。
let number = 5
number = 6 //This will not compile.
Var是一个变量,可以更改(但是在将其定义为其他数据类型之后)。
var number = 5
number = 6 //This will compile.
如果您尝试将变量更改为其他dataType,它将无法正常工作
var number = 5
number = "Hello World" //This will not compile.
主要区别在于var
变量值可以更改,而let
不能更改。如果要让用户输入数据,则可以使用,var
以便可以更改值,而可以使用let
datatype变量,以便不能更改值。
var str = "dog" // str value is "dog"
str = "cat" // str value is now "cat"
let strAnimal = "dog" // strAnimal value is "dog"
strAnimal = "cat" // Error !
如果是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.
“使用let来创建常量,使用var来生成变量”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
https://itun.es/us/jEUH0.l
即使let和var之间已经有很多区别,但是一个主要区别是:
let is compiled fast in comparison to var.
var
是快速创建变量的唯一方法。var
并不像javascript之类的解释语言一样表示动态变量。例如,
var name = "Bob"
在这种情况下,name
可以推断变量的类型为name为type String
,我们还可以通过显式定义type来创建变量,例如
var age:Int = 20
现在,如果将字符串分配给age,则编译器将给出错误信息。
let
用于声明常量。例如
let city = "Kathmandu"
或者我们也可以
let city:String = "Kathmandu"
如果尝试更改city的值,则在编译时会出错。
资料来源: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"
让我们理解上面的示例:我们用“ var keyword”创建了一个新变量“ a”,并为其分配了值“ 1”。当我打印“ a”时,输出为1。然后将2分配给“ var a”,即我正在修改变量“ a”的值。我可以做到这一点而不会出现编译器错误,因为我将其声明为var。
在第二种情况下,我使用“ let关键字”创建了一个新变量“ b”,并为其分配了值“ 4”。当我打印“ b”时,我得到4作为输出。然后,我尝试将5赋给“ let b”,即我试图修改“ let”变量,然后出现编译时错误“无法分配给值:'b'为'let'常量”。
尽管目前我仍在阅读手册,但是我认为这与C / C ++ const
指针非常接近。换句话说,像之间的差异char const*
和char*
。编译器还拒绝更新内容,而不仅仅是引用重新分配(指针)。
例如,假设您具有此结构。请注意,这是一个结构,而不是一个类。AFAIK,类没有不可变状态的概念。
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
由于这些结构默认情况下是不可变的,因此您需要使用标记一个mutator方法mutating
。并且由于名称aaa1
是常量,因此您无法在其上调用任何mutator方法。这正是我们对C / C ++指针的期望。
我相信这是一种支持const正确性的机制。
使用let关键字声明常量,并使用var关键字声明变量。
let maximumNumberOfLoginAttempts = 10 var currentLoginAttempt = 0
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
在一行中声明多个常量或多个变量,以逗号分隔:
var x = 0.0, y = 0.0, z = 0.0
打印常量和变量
您可以使用println函数打印常量或变量的当前值:
println(friendlyWelcome)
Swift使用字符串插值法将常量或变量的名称作为较长字符串中的占位符
将名称括在括号中,并在左括号前使用反斜杠将其转义:
println("The current value of friendlyWelcome is \(friendlyWelcome)")
找到了一个很好的答案,希望可以帮助您:)
let
并不意味着对象是不可变的,而是意味着指针是不可变的。要获得Obj-C中的等效功能,您需要使用NSObject *const myObject = someobject;
-可以修改此类对象的属性,但myObject
不能修改指针以指向另一个对象。
const pointer
不能在未来的变化,但它的价值就可以了。您不能重新初始化它,但可以根据需要使用它。