答 《卓同学的 Swift 面试题》

原题的链接:http://www.jianshu.com/p/7c7f4b4e4efe

1. class 和 struct 的区别

一个引用类型,一个值类型

2. 不通过继承,代码复用(共享)的方式有哪些

在swift 文件里直接写方法,相当于一个全局函数。
extension 给类直接扩展方法。

3. Set 独有的方法有哪些?

不会出现重复的值。
里面的元素必须时相同的类型。

4. 实现一个 min 函数,返回两个元素较小的元素
func min<T : Comparable>(_ a : T , b : T) -> T {
    return a < b ? a : b
}
5. map、filter、reduce 的作用

map : 映射 , 将一个元素根据某个函数 映射 成另一个元素(可以是同类型,也可以是不同类型)
filter : 过滤 , 将一个元素传入闭包中,如果返回的是false , 就过滤掉
reduce :先映射后融合(这样说容易理解) , 将数组中的所有元素映射融合在一起。举个例子:
求所有人的钱的总和,这里钱是字符串表示的

struct Person {
    let name : String
    let money : String
}
let a = Person(name: "小王", money: "5.0")
let b = Person(name: "小李", money: "7.1")
let c = Person(name: "小张", money: "3.22")

let sumMoney = [a , b , c].reduce(0) {
    return $0 + ($1.money as NSString).doubleValue
}
print(sumMoney)
//15.32
6. map 与 flatmap 的区别

map不能将元素映射成可选类型,flatmap可以

7. 什么是 copy on write

百度

8. 如何获取当前代码的函数名和行号

函数名#functio 行号#line 文件名#file

9. 如何声明一个只能被类 conform 的 protocol
protocol OnlyClassProtocol : class {

}
10. guard 使用场景

相当于

if !(...) {
  return
}

可以理解为拦截,凡是不满足 guard 后面条件的,都不会再执行下面的代码。
我一般用来解包 。 不能解包的, 就不能执行下面的代码

11. defer 使用场景

在一对花括号 : { } 里 使用defer ,这个defer 里面的内容将会在结束 {} 前(or 后?) 被执行

defer
11. String 与 NSString 的关系与区别

能够互相转换,一个值类型,一个引用类型

12. 怎么获取一个 String 的长度
print( "abcdefg".characters.count ) 
//7

("abcdefg" as NSString).length //这个要算作NSString的获取长度的方法
13. throws 和 rethrows 的用法与作用

throws 声明在函数的末尾,表示这个函数会抛出 Error的子类.
rethrows 再传入throws的闭包时,这个函数返回用rethrows

14. try? 和 try!是什么意思

try! 强制抛出错误,有错误就会崩溃
try? 抛出错误,没错误不会崩溃直接返回
try :

WX20170315-175706.png

如果不用do catch , 就会编译报错

WX20170315-175838.png

如果函数后面加上 throws , 将错误传递下去. 即使不用都do catch 编译也不会报错。 但是调用throwfun2()还是要使用do catch

14. associatedtype 的作用

相当于protocol的范型

protocol Animal {
    associatedtype AnimalType : Comparable
}

extension Animal {
    typealias AnimalType = Self
}
13. 什么时候使用 final

不允许class 被继承
不允许函数被重写

14. public 和 open 的区别

没用过 百度吧

15. 声明一个只有一个参数没有返回值闭包的别名
typealias NoReturn = (String) -> Void
16. Self 的使用场景

表示自己本身的类型,见14的例子

17. dynamic 的作用

动态化。用的少

18. 什么时候使用 @objc

与oc交互。

19. Optional(可选型) 是用什么实现的

enum 和 重载符号 ?

20. 如何自定义下标获取
WX20170315-182238.png

Array的文档

21. ?? 的作用

当 ?? 前面的值为nil 的时候就取 ??后面的值

22. lazy 的作用

只有属性被调用的时候才会执行lazy

WX20170315-183000.png

如果直接给属性赋值

WX20170315-183118.png
22. 一个类型表示选项,可以同时表示有几个选项选中(类似 UIViewAnimationOptions ),用什么类型表示

继承了OptionSet的struct , enum 。 class 没有试过,应该也可以

23. inout 的作用

改变函数外的值

24. Error 如果要兼容 NSError 需要做什么操作

不明白

25. 下面的代码都用了哪些语法糖 [1, 2, 3].map{ $0 * 2 }

用$0 捕获第一个参数。
只有一行代码的时候, 隐藏掉了 return 。

26. 什么是高阶函数

Curry化? 百度

27. 如何解决引用循环

weak unowned 关键字

28. 下面的代码会不会崩溃,说出原因
var mutableArray = [1,2,3]
for _ in mutableArray {
  mutableArray.removeLast()
}

在原题主的评论里有了

29. 给集合中元素是字符串的类型增加一个扩展方法,应该怎么声明
WX20170315-184548.png

参考文档的写法

WX20170315-184721.png

报错了。


WX20170315-185021.png

所以用了一个投机取巧的办法

30. 定义静态方法时关键字 static 和 class 有什么区别

struct 只能用static
class 的属性只能用 static , 其他地方都能随便用。
反正编译器会告诉你的

31. 一个 Sequence 的索引是不是一定从 0 开始?

不是。
ArraySlice是Sequence的子类,ArraySlice就不是

32. 数组都实现了哪些协议

翻文档?😎

33. 如何自定义模式匹配

不明白

34. autoclosure 的作用

可以传值或者有返回值的闭包。

35. 编译选项 whole module optmization 优化了什么

不知道

36. 下面代码中 mutating 的作用是什么
struct Person {

  var name: String {
      mutating get {
          return store
      }
  }
}

mutating 表示这个方法会(有可能)修改这个结构体, 只有var 的结构体才能调用mutation的方法

37. 如何让自定义对象支持字面量初始化

翻文档


WX20170315-192132.png
WX20170315-192404.png
38. dynamic framework 和 static framework 的区别是什么

动态库和静态库。不知道

39. 为什么数组索引越界会崩溃,而字典用下标取值时 key 没有对应值的话返回的是 nil 不会崩溃。

不知道。
但是原题主的评论已有答案。

40. 一个函数的参数类型只要是数字(Int、Float)都可以,要怎么表示。
func isNumber<T : SignedNumber>(_ number : T){
print("yes, it is a number")
}

推荐阅读更多精彩内容