Swift为什么将String、Array、Dictionary
Swift 基本数据类型:整型Integet,浮点型float,布尔值Boolean,字符串String,数组Array,字典Dictioanry都是值类型,并在底层都是以结构体的形式所实现。
类是引用类型。
测试数组是否为值类型:
var testArray = [String]()
testArray.append("a")
testArray.append("b")
testArray.append("c")
var testArray2 = testArray
print("testArray=\(testArray)") //输出:testArray=["a", "b", "c"]
print("testArray2=\(testArray2)") //输出:testArray2=["a", "b", "c"]
testArray2.removeAll() //将testArray2中的元素全部remove
print("testArray=\(testArray)") //输出:testArray=["a", "b", "c"]
print("testArray2=\(testArray2)") //输出:testArray2=[]
测试字典是否为值类型:
var testDictionary = [String: String]()
testDictionary.updateValue("a", forKey: "1")
testDictionary.updateValue("b", forKey: "2")
var testDictionary2 = testDictionary
print("testDictioanry=\(testDictionary)") //输出:testDictioanry=["2": "b", "1": "a"]
print("testDictioanry2=\(testDictionary2)") //输出:testDictioanry2=["2": "b", "1": "a"]
testDictionary2.removeAll()
print("testDictioanry=\(testDictionary)") //输出:testDictioanry=[ "2": "b", "1": "a"]
print("testDictioanry2=\(testDictionary2)") //输出:testDictioanry2=[:]
测试类是否为引用类型:
class LTClass{
var age: Int = 18
var name: String?
func printParams(){
print("age=\(age), name=\(name)")
}
}
var ltc = LTClass()
var ltc2 = ltc
print("ltc=\(ltc)") //输出:ltc=SwiftValueTypeTest.LTClass
print("ltc2=\(ltc2)") //输出:ltc2=SwiftValueTypeTest.LTClass
print("printParams:")
ltc.printParams() //输出:age=18, name=nil
ltc2.printParams() //输出:age=18, name=nil
//修改ltc的名字
ltc.name = "TOTTI"
ltc.printParams() //输出:age=18, name=Optional("TOTTI")
ltc2.printParams() //输出:age=18, name=Optional("TOTTI")
通过上面三段代码的可以很清晰的确定Array,Dictionary为值类型。类为引用类型
这么设计是什么原因呢?
1、值类型相比引用类型,最大的优势在于内存使用的高效。值类型在栈上操作,引用类型在堆上操作。栈上的操作仅仅是单个指针的上下移动,而堆上的操作会设计很多的移位、合并、重新链接等。也就是说这么设计,大幅减少了堆上的内存分配和回收的次数。
2、String、Array、Dictionary设计成值类型,也是为了线程安全考虑。通过Swift的let设置,是这些数据真正达到了“不变”,也从根本上解决了多线程内存访问和操作的问题
3、设计成值类型还可以提升App的灵活度。例如:通过实现Collection这样的协议,可以遍历String,是的整个开发更加灵活高效