天天看點

Swift程式設計小技巧

Swift程式設計小技巧

swift tips

Swift中有很多有用的小技巧,用好了能使代碼更加安全,簡潔,易于了解或效率更加高效,在這記錄一些編寫swifty code的小技巧。

1、for in 循環中的可選值解包

當使用

for in

循環一個包含可選值的數組時,我們可能會使用

if let

guard

解包:

let animals = ["dog", nil, "pig", "cat", nil]
 for obj in animals {
     if let animal = obj {
         print(animal)
     }
 }           

複制

上述代碼完全沒問題,但是我們可以在

for in

中使用

case let

來簡化代碼:

for case let animal? in animals {
    print(animal)
}           

複制

或者使用

compactMap

解包,可以參考Swift:map(), flatMap() 和 compactMap() 的差別:

for animal in animals.compactMap({$0}) {
    print(animal)
}           

複制

如上兩種方法都能時代碼更加簡潔

2、for in 循環中使用 where 語句

我們都會遇到寫類似如下代碼的地方:

let items = [1, 2, 3, 4]
for item in items {
    if(item % 2 == 0) {
        print(item)
    }
}
Output: 2 4            

複制

使用where語句可以使代碼變得更簡潔:

for item in items where item % 2 == 0 {
    print(item)
}
Output: 2 4           

複制

3、使用filter + forEach替代 for in + where

let items = [1, 2, 3, 4]
items.filter{$0 % 2 == 0}.forEach {
    print($0)
}           

複制

可以看出代碼簡潔度并沒有很大的提升,但是語義更加清晰更容易了解。

4、Defer保證代碼塊在控制流退出前被調用

defer 所聲明的代碼塊會在目前代碼執行退出後被調用:

func test(code: Int) {
    defer {
        print("end print in defer")
    }
    if code < 0 {
        print("less than 0")
        return
    }
    if code > 10 {
        print("big than 10")
    }
}
test(code: -1)
test(code: 11)

Output:
less than 0
end print in defer
big than 10
end print in defer           

複制

Objective-C中也可以實作類似的功能,可以參考:Objective-C中實作Swift中的defer

5、布爾值取反

在任何程式設計語言中,布爾值都是最常用和最簡單的資料類型之一。而取反操作也是非常常見的,比如:

var isSelect = true
if isSelect {
  isSelect = false
}           

複制

上面的代碼應該不會有人寫吧,這很難說哦,哈哈哈

if isSelect {
  isSelect = !isSelect
}           

複制

這種寫法應該人多一些,也不容易出錯一些,但是我覺得下面的更好:

if isSelect {
  isSelect.toggle()
}           

複制

toggle()是一個swift提供的函數,用來切換布爾變量的值。

6、數組内元素的類型轉換

常見的情況在擷取一個視圖的所有子視圖後,需要給某一類視圖做一些操作,以

UILabel

為例

  • 使用for in 循環
for subview in self.view.subviews {
    if subview is UILabel {
        (subview as! UILabel).text = "find"
    }
}

for subview in self.view.subviews where subview is UILabel {
   (subview as! UILabel).text = "find"
}

for subview in self.view.subviews.compactMap({$0 as? UILabel}) {
    subview.text = "find"
}

for case let subview as UILabel in self.view.subviews {
    subview.text = "find"
}           

複制

此處for in 循環中明顯使用 case let 和 compactMap是最方遍,代碼最簡潔的

  • compactMap的另一種使用
self.view.subviews
    .compactMap{$0 as? UILabel}
    .forEach {
        $0.text = "find"
}           

複制

個人比較推薦這一種寫法,語義更加清晰

7、同時周遊數組的索引和元素

let array = ["a","b","c","d"]
for (index, element) in array.enumerated() {
    print("\(index)--\(element)")
}           

複制

利用元組在swift中周遊出索引和元素非常簡潔,OC中需要使用

enumerateObjectsUsingBlock

來實作

[array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    NSLog(@"%d -- %@", idx, obj);   
}];           

複制

8、靜态工廠方法

在Swift使用靜态工廠方法和屬性來執行對象的設定可能是一種将設定代碼與實際邏輯清晰分開的好方法,具體可以參考:Swift:靜态工廠方法