一、class和struct的区别:
1.从类型上来说:
- struct 是值类型,值类型在传递和赋值时将进行复制。
- class是引用类型,是一个引用对象的指向。
2.从功能上来说
- class可以继承,这样子类可以使用父类的特性和方法。
- class类型可以在runtime的时候检查和解释一个实例的类型。
- 可以用deinit来释放资源。
- 一个类可以被多次引用。
- struct 结构较小,适用于复制操作,相比于一个class的实例被多次引用更加安全。
- struct 无需担心内存memory leak或者多线程冲突问题。
二、class里修饰的变量与函数和struct里修饰的变量与函数有什么区别,会出现什么结果,为什么
这篇文章讲的很详细
swift class和struct的区别(结构体和类的区别)
- 1.struct会自动生成需要的构造方法(constructor),哪个属性没有赋初始值就会生成以哪个属性为参数的构造方法。而class没有,要自己写
struct StructTest {
var name:String
var age:Int
}
class ClassTest {
var name:String?
var age:Int?
}
var structTest = StructTest(name: "", age: 0)
var classTest = ClassTest()
- 2.struct的属性可以不赋初始值,而class的属性必须赋初始值或者设为可选类型,下面也是可以的,
区别只是struct自动生成了带参数的init方法
class Test: Equatable{
var age: NSNumber
var name:String
init(age: NSNumber, name: String) {
self.age=age
self.name = name
}
}
var test1 = Test(age: 11, name: "王麻子")
let test2 = Test(age: 12, name: "张三")
- 2.1 class遵守了协议没有实现方法会报错,而结构体(struct)不会
class代码如下:
class Test: Equatable{
var age: NSNumber
var name:String
// static func == (lhs: Test, rhs: Test) -> Bool {
// if lhs.name == rhs.name {
// return true
// }else{
// return false
// }
// }
init(age: NSNumber, name: String) {
self.age=age
self.name = name
}
}
var test1 = Test(age: 11, name: "王麻子")
let test2 = Test(age: 12, name: "张三")
print(test1 == test2)
struct代码如下:
struct Test: Equatable{
var age: NSNumber
var name:String
// static func == (lhs: Test, rhs: Test) -> Bool {
// if lhs.name == rhs.name {
// return true
// }else{
// return false
// }
// }
// init(age: NSNumber, name: String) {
// self.age=age
// self.name = name
// }
}
var test1 = Test(age: 11, name: "王麻子")
let test2 = Test(age: 12, name: "张三")
print(test1 == test2)
- 3.struct是值类型(Value Type),深拷贝。class是引用类型(Reference Type),浅拷贝。
struct StructTest {
var name:String = "struct1"
var age:Int = 0
}
class ClassTest {
var name:String = "class1"
var age:Int = 0
}
var structTest1 = StructTest()
var structTest2 = structTest1
structTest2.name = "structTest2"
print("structTest1.name = \(structTest1.name)")
var classTest1 = ClassTest()
classTest1.name = "class1"
let classTest2 = classTest1
classTest2.name = "class2"
print("classTest1.name = \(classTest1.name)")
从代码可以看出,当classTest2.name的值变了之后,classTest1.name的值也跟着变了。而structTest1.name的值没有跟着structTest2.name的值变化。而classTest2前面用let修饰,依然可以改变classTest2.name的值。而要改变structTest2.name的值,structTest2前面必须用var修饰变量。
- 3.1 class中可以有单例对象属性,struct中不能有
在 struct中创建单例时,必须要在let前加static,不然会报错,而class不需要
struct MyFileManager{
static let name = MyFileManager()
static var routesPath:String{
guard var pathFile = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first else { return "" }
pathFile += "/routes.plist"
return pathFile
}
}
class MyFileManager{
let name = MyFileManager()
static var routesPath:String{
guard var pathFile = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first else { return "" }
pathFile += "/routes.plist"
return pathFile
}
}
- 4.struct不能继承,class可以继承
- 5.NSUserDefaults:struct 不能被序列化成 NSData 对象,无法归解档
- 6.当你的项目的代码是 Swift 和 Objective-C 混合开发时,你会发现在 Objective-C 的代码里无法调用 Swift 的 Struct。因为要在 Objective-C 里调用 Swift 代码的话,对象需要继承于 NSObject。
- 7.内存分配:struct分配在栈中,class分配在堆中。struct比class更“轻量级”(struct是跑车跑得快,class是SUV可以载更多的人和货物)
三、Swift的那些地方用到高阶函数(map和flatMap的区别)
Swift 中的高阶函数有:map、flatMap、compactMap、filter、reduce。
-
map函数对数组中每一个元素进行一次运算,元素不匹配或为空时返回 nil ,不会把 optional 类型解包
let scores = ["1", "2", "three", "four", "5"]
let mapped: [Int?] = scores.map { str in Int(str) }
print(mapped)
// [1, 2, nil, nil, 5]
-
flatMap
1.函数也能对数组中每一个元素进行一次运算,元素不匹配时或为空时会过滤掉什么也不返回,,会把 optional 类型解包
let compactMapped: [Int] = scores.flatMap { str in Int(str) }
print(compactMapped)
// [1, 2, 5]
2.flatMap会把一个N维数组转换成一个一维数组返回,map还是返回它本身。
//map
let stringArray = [["Objective-C", "Swift"], ["Python", "HTML5", "C",""]]
let resultAry = stringArray.map { $0 }
print(resultAry)
//[["Objective-C", "Swift"], ["Python", "HTML5", "C", ""]]
//flatMap
let stringArray1 = [["Objective-C", "Swift"], ["Python", "HTML5", "C",""]]
let resultAry1 = stringArray1.flatMap { $0 }
print(resultAry1)
//["Objective-C", "Swift", "Python", "HTML5", "C", ""]
3.flatMap会把两个不同的数组合并成一个数组,返回的元素个数为两个数组元素个数的乘积。
let fruits = ["Apple", "Orange", "Puple", "Pear"]
let counts = [2, 3, 6, 1]
let arrayMerge = counts.flatMap { (count) -> [String] in
fruits.map({ return $0 + ": \(count)"})
}
print("arrayMerge = \(arrayMerge)")
/*
返回结果:
arrayMerge = ["Apple: 2", "Orange: 2", "Puple: 2", "Pear: 2", "Apple: 3", "Orange: 3", "Puple: 3", "Pear: 3", "Apple: 6", "Orange: 6", "Puple: 6", "Pear: 6", "Apple: 1", "Orange: 1", "Puple: 1", "Pear: 1"]
*/
-
compactMap,过滤数组中返回为nil的元素
let scores = ["1", "2", "three", "four", "5"]
let mapped: [Int?] = scores.map { str in Int(str) }
// [1, 2, nil, nil, 5] - Two nil values as "three" and "four" are strings.
print(mapped)
let compactMapped: [Int] = scores.compactMap { str in Int(str) }
// [1, 2, 5] - The nil values for "three" and "four" are filtered out.
print(compactMapped)
网友评论