Swift 面試真題:五問 Any 和 AnyObject

閱讀本文前,假設你已經熟悉 Swift 的 Any 和 AnyObject 的相關知識。

請寫出下面程序的運行結果:包含“寫出輸出”和“編譯失敗”兩種情況。

Swift版本:3.2、3.3、4.0、4.1

題1

let s: AnyObject = "This is a bridged string." as NSString
print(s is NSString)
print(s is String)

運行結果

true
true

知識點

  1. NSString 和 String 會自動bridge
  2. 第一行中的as不應該使用as!或者as?

題2

var arr = [AnyObject]()
arr.append(NSDate())
arr.append(Date())
print(arr is [NSDate])

運行結果

編譯不過:
Argument type 'Date' does not conform to expected type 'AnyObject'

知識點
AnyObject 只支持 class type,NSDate 是引用類型,而 Date 是個 struct

題3

var arr = [AnyObject]()
arr.append(NSDate())
print(arr is Array<NSDate>)
print(arr is Array<Date>)
print(arr is Any)
print(arr is [Any])

運行結果

true
true  // 有些環境下此處是false。
true
true

知識點

  1. 前兩個運行時執行判斷,非O(1)算法;如果再 append(NSData()),則這兩個輸出爲false。
  2. NSDate 和 Date 可自動 bridge。
  3. 後兩個可以編譯期推斷爲 true。

題4

var arr = [Int]()
arr.append(12)
var arr2 = arr as [AnyObject] as [Any]
arr2.append(1.0)
print(arr2[0])
print(arr.count)

運行結果

12
1

知識點

  1. [Int] 數組可以轉成 [AnyObject],此處發生了 Int 往NS引用類型的隱式轉換,不然一個Int不可能是一個 AnyObject。
  2. Array 是值類型,因此 append 在 arr2 的1.0,不影響 arr。

題5

var arr = [Int]()
arr.append(12)
var arr2 = arr ______
// 以下三種情況分別程序結果爲何
// as [AnyObject]
// as [AnyObject] as [Any]
// as [Any]
arr2.append(1.0)
print(type(of:arr2[0]))
1. as [AnyObject]

運行結果

編譯不過:
Argument type 'Double' does not conform to expected type 'AnyObject'

知識點
arr2.append(1.0) 編譯不通過。1.0 是值類型,而數組是 [AnyObject] 只接受引用類型。

2. as [AnyObject] as [Any]

運行結果

__NSCFNumber

知識點
回答NSNumber也算對。兩次轉換成 [Any] 因此後續的 append(1.0) 可以編譯通過;
由於 Int 是值類型,[Int ]轉換成 [AnyObject] 的時候,Int 自動轉換成 NSNumber 引用類型。

3. as [Any]
Int

知識點
Any 可以代表任何類型,此處不發生 Int 到 NSNumber 類型的自動轉換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章