Swift: 可變參數

轉自: https://addicechan.github.io/...html

Swift中,命名一個方法參數的時候,若是有多個特定類型的參數,能夠直接使用可變參數(Variadic Parameters)。官網文檔連接git

使用可變參數,其實很簡單。就是在參數類型加上。好比Int…。實際上,方法內部去調用該參數的話,Xcode提示的是[Int]。也就是一個Array。這樣也是大大方便。不用非得去聲明一個[Int]github

小二。。上代碼~~~objective-c

// 多數字相加
func add(_ values: Int...) -> Int {
    return values.reduce(0){ $0 + $1 }
}

print(add(1,5,8,9))
// 23

再好比,能夠封裝一個UIAlertController。若是以爲每次得寫一大堆alert.addAction() 巴拉巴拉.swift

extension UIAlertController {

    class func show(_ vc: UIViewController?, title: String, msg: String, style: UIAlertControllerStyle ,btns: String... ,completionHandler:@escaping ((_ btnIndex: Int) -> Void)) {
        let alertController : UIAlertController = UIAlertController(title: title, message: msg, preferredStyle: style)
        
        for (index, element) in btns.enumerated() {
            alertController.addAction(UIAlertAction(title: element, style: .default, handler: { _ in
                completionHandler(index)
            }))
        }
        
        if style == .actionSheet {
            alertController.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: nil))
        }
        
        vc?.present(alertController, animated: true, completion: nil)
    }
}

// 使用
UIAlertController.show(self, title: "Alert", msg: "show alert", style: .alert, btns: "previous", "next") { index in
         print(index)
}

不過,可變參數沒法用於Objective-C中。api

Objective-C若是要使用可變參數。那麼須要使用到va_list等系列C函數app

小二,繼續上代碼~~~函數

- (NSString *)add:(NSString *)value, ... NS_REQUIRES_NIL_TERMINATION {
    NSMutableString *result = [NSMutableString string];
    [result appendString:value];
    if (value) {
        va_list values;
        // values 會從 value 的指針地址開始取值,直至nil
        va_start(values, value);
        id tempValue;
        while((tempValue = va_arg(values, NSString *))) {
            [result appendString:tempValue];
        }
        
        // 記得清空
        va_end(values);
    }
    return result;
}

使用va_start這個宏,會從value的指針地址開始,一個一個的去取值。對於非指針的話,那麼就沒法實現。至於 方法名後面的NS_REQUIRES_NIL_TERMINATION,則是在方法調用的時候,加上nil做爲終結。由於若是沒有nil的話,那麼也是會致使 不停的取值,因而,拿到未初始化的內存空間後,就致使崩潰啦。Boom....指針

寫完這個方法後,只能感嘆下Swift封裝的太好了。很方便的...語法,加上高階函數的使用。貌似也不太算很公正的對比。(逃。code

func add(_ values: String...) -> String {
    return values.reduce(""){ $0 + $1 }
}

這樣幾行代碼,就已經實現了上述Objective-C寫的方法了。

寫這篇的根源,實際上是在翻(gen)看(ben)Swift(jiu)的(bu)官(zhi)方(dao)文(de)檔(shuo)。因而看到可變參數這玩意了。後來想一想,Objective-CNSArrayUIAlertView等,其實也是基於這樣去寫的。

算是又明白了一些。希望不太遲。

哭瞎了。。。

相關文章
相關標籤/搜索