接中篇,答“卓同學(xué)的 Swift 面試題”--中篇
上篇鏈接:答“卓同學(xué)的 Swift 面試題”--上篇
面試題鏈接:卓同學(xué)的 Swift 面試題
在此篇中,回答面試題基礎(chǔ)篇的最后13道題:
24. Optional(可選型) 是用什么實(shí)現(xiàn)的
25. 如何自定義下標(biāo)獲取
26. ?? 的作用
27. lazy 的作用
28. 一個(gè)類(lèi)型表示選項(xiàng),可以同時(shí)表示有幾個(gè)選項(xiàng)選中(類(lèi)似 UIViewAnimationOptions ),用什么類(lèi)型表示
29. inout 的作用
30. Error 如果要兼容 NSError 需要做什么操作
31. 下面的代碼都用了哪些語(yǔ)法糖
[1, 2, 3].map{ $0 * 2 }
32. 什么是高階函數(shù)
33. 如何解決引用循環(huán)
34. 下面的代碼會(huì)不會(huì)崩潰,說(shuō)出原因
var mutableArray = [1,2,3]
for _ in mutableArray {
mutableArray.removeLast()
}
35. 給集合中元素是字符串的類(lèi)型增加一個(gè)擴(kuò)展方法,應(yīng)該怎么聲明
36. 定義靜態(tài)方法時(shí)關(guān)鍵字 static 和 class 有什么區(qū)別
24. Optional(可選型) 是用什么實(shí)現(xiàn)的
- Optional 是個(gè)枚舉。有兩個(gè)枚舉成員,
Some(T)和None - 通關(guān)泛型來(lái)兼容所有類(lèi)型
25. 如何自定義下標(biāo)獲取
使用subscript語(yǔ)法
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
threeTimesTable[6] //18
26. ?? 的作用
?? 是空合運(yùn)算符。
比如a ?? b ,將對(duì)可選類(lèi)型a進(jìn)行為空判斷,如果a包含一個(gè)值,就進(jìn)行解封,否則就返回一個(gè)默認(rèn)值b。
表達(dá)式 a 必須是 Optional 類(lèi)型。默認(rèn)值 b 的類(lèi)型必須要和 a 存儲(chǔ)值的類(lèi)型保持一致
27. lazy 的作用
使用lazy關(guān)鍵字修飾struct 或class 的成員變量,達(dá)到懶加載的效果。一般有以下使用場(chǎng)景:
- 屬性開(kāi)始時(shí),還不確定是什么活著還不確定是否被用到
- 屬性需要復(fù)雜的計(jì)算,消耗大量的CPU
- 屬性只需要初始化一次
28. 一個(gè)類(lèi)型表示選項(xiàng),可以同時(shí)表示有幾個(gè)選項(xiàng)選中(類(lèi)似 UIViewAnimationOptions ),用什么類(lèi)型表示
使用選項(xiàng)集合:OptionSet
具體參見(jiàn):Swift 中的選項(xiàng)集合
29. inout 的作用
可以讓值類(lèi)型以引用方式傳遞,比如有時(shí)需要通過(guò)一個(gè)函數(shù)改變函數(shù)外面變量的值,例如:
var value = 50
print(value) // 此時(shí)value值為50
func increment(inout value: Int, length: Int = 10) {
value += length
}
increment(&value)
print(value) // 此時(shí)value值為60,成功改變了函數(shù)外部變量value的值
30. Error 如果要兼容 NSError 需要做什么操作
想讓我們的自定義Error可以轉(zhuǎn)成NSError,實(shí)現(xiàn)CustomNSError就可以完整的as成NSError
/// Describes an error type that specifically provides a domain, code,
/// and user-info dictionary.
public protocol CustomNSError : Error {
/// The domain of the error.
public static var errorDomain: String { get }
/// The error code within the given domain.
public var errorCode: Int { get }
/// The user-info dictionary.
public var errorUserInfo: [String : Any] { get }
}
話說(shuō)這也是從卓同學(xué)的文章摘取來(lái)的??: Swift 3必看:Error與NSError的關(guān)系
31. 下面的代碼都用了哪些語(yǔ)法糖
[1, 2, 3].map{ $0 * 2 }
- 尾隨閉包(Trailing Closures), 如果函數(shù)的最后一個(gè)參數(shù)是閉包,則可以省略
() - 如果該閉包只有一行,則可以省略
return - 類(lèi)型推斷,返回值被推斷為
Int -
$0代表集合的元素
32. 什么是高階函數(shù)
- 接受一個(gè)或多個(gè)函數(shù)作為參數(shù)
- 把一個(gè)函數(shù)當(dāng)作返回值
- 例如Swift中的
mapflatMapfilterreduce
33. 如何解決循環(huán)引用
可以使用 weak 和 unowned
“Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialization.”
在引用對(duì)象的生命周期內(nèi),如果它可能為nil,那么就用weak引用。反之,當(dāng)你知道引用對(duì)象在初始化后永遠(yuǎn)都不會(huì)為nil就用unowned
34. 下面的代碼會(huì)不會(huì)崩潰,說(shuō)出原因
var mutableArray = [1,2,3]
for _ in mutableArray {
mutableArray.removeLast()
}
不會(huì)崩潰。迭代器?不知道咋解釋。等搞明白再來(lái)填上。。。如有知道的,請(qǐng)指教。
35. 給集合中元素是字符串的類(lèi)型增加一個(gè)擴(kuò)展方法,應(yīng)該怎么聲明
extension Sequence where Iterator.Element == Int {
//your code
}
protocol SomeProtocol {}
extension Collection where Iterator.Element: SomeProtocol {
//your code
}
36. 定義靜態(tài)方法時(shí)關(guān)鍵字 static 和 class 有什么區(qū)別
-
static和class都是用來(lái)指定類(lèi)方法 -
class關(guān)鍵字指定的類(lèi)方法** 可以被override** -
static關(guān)鍵字指定的類(lèi)方法** 不能被override**