目录
String 与 NSString 的关系与区别
Swift字符串的Range截取
throws 和 rethrows 的用法与作用
fileprivate和internal修饰符
open与public的区别?
swift中 closure 与OC中block的区别
swift中,如何阻止方法,属性,下标被子类改写?
associatedtype 的作用
try? 和 try!是什么意思
map、filter、reduce 的作用?
defer、guard的作用?
如何自定义下标获取
这段复杂的代码按字母顺序对名称数组进行排序。尽可能简化闭包。
什么是可选的,可选可以解决哪些问题?
构体和类之间的主要区别。
什么是泛型(通用类型)?它们解决了什么问题?
nil 和 .none有什么区别?
Swift和OC的区别?
swift的派发机制
Struct和Class区别
swift中mutating的作用?
associatedtype 的作用?
什么时候使用 final
定义静态方法时关键字 static 和 class 有什么区别
Self 的使用场景
一个类型表示选项,可以同时表示有几个选项选中(类似 UIViewAnimationOptions ),用什么类型表示
inout 的作用
Error 如果要兼容 NSError 需要做什么操作
什么是高阶函数
如何解决引用循环
下面的代码会不会崩溃,说出原因
给集合中元素是字符串的类型增加一个扩展方法,应该怎么声明
一个 Sequence 的索引是不是一定从 0 开始?
数组都实现了哪些协议
如何让自定义对象支持字面量初始化
为什么数组索引越界会崩溃,而字典用下标取值时 key 没有对应值的话返回的是 nil 不会崩溃
一个函数的参数类型只要是数字(Int、Float)都可以,要怎么表示
不通过继承,代码复用(共享)的方式有哪些
如何自定义模式匹配
swift语法糖?!的本质
什么是函数式编程
let str = "123456789"
let start = str.startIndex//表示str的开始位置
let end = str.endIndex//表示str的结束位置
let startOffset = str.index(start, offsetBy: 2)//表示str的开始位置 + 2
let endOffset = str.index(end, offsetBy: -2)//表示str的结束位置 - 2
print(str[start])//输出 1 第1个字符
print(str[startOffset])//输出 3 第3个字符
print(str[endOffset])//输出 8 第8个字符(10-2)
print(str[end])//报错!因为实endIndex指向第10个字符,而第10个字符是不存在的
let range1:ClosedRange = 1 ... 4
let range2:CountableClosedRange = 1 ... 4
let range3:Range = 1 ..< 4
let range4:CountableRange = 1 ..< 4
let array = ["a", "b", "c", "d", "e", "f"]
print(array[range1])
print(array[range2])
print(array[range3])
print(array[range4])
输出:
["b", "c", "d", "e"]
["b", "c", "d", "e"]
["b", "c", "d"]
["b", "c", "d"]
//协议,使用关联类型
protocol TableViewCell {
associatedtype T
func updateCell(_ data: T)
}
//遵守TableViewCell
class MyTableViewCell: UITableViewCell, TableViewCell {
typealias T = Model
func updateCell(_ data: Model) {
// do something ...
}
}
extension AnyList {
subscript(index: Int) -> T{
return self.list[index]
}
subscript(indexString: String) -> T?{
guard let index = Int(indexString) else {
return nil
}
return self.list[index]
}
}
类型推断系统会自动判断闭包中参数的类型和返回类型,就可以去掉类型:
animals.sort { (one, two) -> Bool in
return one < two
}
可以用$I符号替换参数名:
animals.sort { return $0 < $1 }
在单语句闭包中,可以省略返回关键字。最后一条语句的值将成为闭包的返回值:
animals.sort { $0 < $1 }
后,由于Swift知道数组的元素符合equatable,因此可以简单地编写:
animals.sort(by: <)
func areIntEqual(_ x: Int, _ y: Int) -> Bool {
return x == y
}
func areStringsEqual(_ x: String, _ y: String) -> Bool {
return x == y
}
areStringsEqual("ray", "ray") // true
areIntEqual(1, 1) // true
通过采用泛型,可以将这两个函数合并为一个函数,同时保持类型安全。下面是通用实现:
func areTheyEqual(_ x: T, _ y: T) -> Bool {
return x == y
}
areTheyEqual("ray", "ray")
areTheyEqual(1, 1)
由于在本例中测试的是相等性,所以将参数限制为遵守 Equatable 协议的任何类型。此代码实现了预期的结果,并防止传递不同类型的参数。
protocol ListProtcol {
associatedtype Element
func push(_ element:Element)
func pop(_ element:Element) -> Element?
}
class IntList: ListProtcol {
typealias Element = Int // 使用 typealias 指定为 Int
var list = [Element]()
func push(_ element: Element) {
self.list.append(element)
}
func pop(_ element: Element) -> Element? {
return self.list.popLast()
}
}
class DoubleList: ListProtcol {
var list = [Double]()
func push(_ element: Double) {// 自动推断
self.list.append(element)
}
func pop(_ element: Double) -> Double? {
return self.list.popLast()
}
}
class AnotherClass {
static func staticMethod(){}
class func classMethod(){}
}
class ChildOfAnotherClass: AnotherClass {
override class func classMethod(){}
//override static func staticMethod(){}// error
}
protocol CopyProtocol {
func copy() -> Self
}
struct SomeStruct: CopyProtocol {
let value: Int
func copySelf() -> SomeStruct {
return SomeStruct(value: self.value)
}
}
class SomeCopyableClass: CopyProtocol {
func copySelf() -> Self {
return type(of: self).init()
}
required init(){}
}
struct SomeOption: OptionSet {
let rawValue: Int
static let option1 = SomeOption(rawValue: 1 << 0)
static let option2 = SomeOption(rawValue:1 << 1)
static let option3 = SomeOption(rawValue:1 << 2)
}
let options: SomeOption = [.option1, .option2]
func swap( a: inout Int, b: inout Int) {
let temp = a
a = b
b = temp
}
var a = 1
var b = 2
print(a, b)// 1 2
swap(a: &a, b: &b)
print(a, b)// 2 1
SomeError.someError as NSError
但是这样没有错误码, 描述等等, 如果想和 NSError 一样有这些东西, 只需要实现 LocalizedError
和 CustomNSError
协议, 有些方法有默认实现, 可以略过, 如:enum SomeError: Error, LocalizedError, CustomNSError {
case error1, error2
public var errorDescription: String? {
switch self {
case .error1:
return "error description error1"
case .error2:
return "error description error2"
}
}
var errorCode: Int {
switch self {
case .error1:
return 1
case .error2:
return 2
}
}
public static var errorDomain: String {
return "error domain SomeError"
}
public var errorUserInfo: [String : Any] {
switch self {
case .error1:
return ["info": "error1"]
case .error2:
return ["info": "error2"]
}
}
}
print(SomeError.error1 as NSError)
// Error Domain=error domain SomeError Code=1 "error description error1" UserInfo={info=error1}
var mutableArray = [1,2,3]
for _ in mutableArray {
mutableArray.removeLast()
}
extension Array where Element == String {
var isStringElement:Bool {
return true
}
}
["1", "2"].isStringElement
//[1, 2].isStringElement// error
ExpressibleBy____Literal
ExpressibleByArrayLiteral
可以由数组形式初始化ExpressibleByDictionaryLiteral
可以由字典形式初始化ExpressibleByNilLiteral
可以由nil 值初始化ExpressibleByIntegerLiteral
可以由整数值初始化ExpressibleByFloatLiteral
可以由浮点数初始化ExpressibleByBooleanLiteral
可以由布尔值初始化Bool : ExpressibleByBooleanLiteral
Int : ExpressibleByIntegerLiteral
Float、Double : ExpressibleByIntegerLiteral、ExpressibleByFloatLiteral
Dictionary : ExpressibleByDictionaryLiteral
String : ExpressibleByStringLiteral
Array、Set : ExpressibleByArrayLiteral
Optinal : ExpressibleByNilLiteral
class MyUrl{
var url:URL
init(string: String){
self.url = URL(string: string)
}
}
extension myUrl:ExpressibleByStringLiteral {
init(stringLiteral value: String) {
self.url = URL(string: value)
}
}
let url:myUrl = "https://www.baidu.com"
print(url.url) // "https://www.baidu.com"
var num: Int = true //错误
extension Int : ExpressibleByBooleanLiteral {
public init(booleanLiteral value: Bool) {
self = value ? 1 : 0
}
}
var num: Int = true //正确
print(num) // 输出:1
Int、Float 都有一个协议
func myMethod(_ value: T) where T: Numeric {
print(value + 1)
}
或者 ExpressibleByIntegerLiteral 协议也行
infix operator =~
func =~ (str: String, pattern: String) -> Bool {
}
infix、 prefix、 postfix 用于自定义表达式的声明, 分别表示 中缀、前缀、后缀
Swift 中没有内置的正则表达式,有一个相似的功能,就是匹配模式
?
和 !
其实分别是Swift语言中对一种可选类型( Optional) 操作的语法糖,Optional
其实是个enum
,里面有None
和Some
两种类型。其实所谓的nil就是Optional.None
, 非nil就是Optional.Some
, 然后会通过Some(T)
包装(wrap)原始值,这也是为什么在使用Optional
的时候要拆包(从enum
里取出来原始值)的原因var name: String?
// 上面这个Optional的声明,是”我声明了一个Optional类型值,
它可能包含一个String值,也可能什么都不包含”,
也就是说实际上我们声明的是Optional类型,而不是声明了一个String类型
(这其实理解起来挺蛋疼的...)