如何在Swift中编写通用的apply()函数? [英] How to write a generic apply() function in Swift?

查看:172
本文介绍了如何在Swift中编写通用的apply()函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以使以下内容在Swift 3中正常工作吗?

Is there any way to get the following working in Swift 3?

 let button = UIButton().apply {
        $0.setImage(UIImage(named: "UserLocation"), for: .normal)
        $0.addTarget(self, action: #selector(focusUserLocation), 
                     for: .touchUpInside)
        $0.translatesAutoresizingMaskIntoConstraints = false
        $0.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        $0.layer.cornerRadius = 5
     }

apply<T>函数应采用类型为(T)->Void的闭包,将其传递给self来运行它,然后简单地返回self.

The apply<T> function should take a closure of type (T)->Void, run it passing self into it, and then simply return self.

另一种选择是为此使用运算符,例如"=>" (从科特林 Xtend 语言.

Another option would be to use an operator for this like "=>" (borrowed the idea from Kotlin and Xtend languages).

试图像这样扩展NSObject:

extension NSObject {   
    func apply<T>(_ block: (T)->Void) -> T
    {
        block(self as! T)
        return self as! T
    }
}

但是它需要在闭包中显式声明参数类型:

But it requires explicit declaration of the parameter type in closure:

let button = UIButton().apply { (it: UIButton) in
        it.setImage(UIImage(named: "UserLocation"), for: .normal)
        it.addTarget(self, action: #selector(focusUserLocation), 
                     for: .touchUpInside)
        ...

这不方便,并且使整个想法不值得付出努力.该类型已在创建对象时指定,并且应该可以不明确地重复该类型.

This is not convenient and makes the whole idea not worth the effort. The type is already specified at object creation and it should be possible not to repeat it explicitly.

谢谢!

推荐答案

HasApply协议

首先让我们定义HasApply协议

protocol HasApply { }

和相关扩展名

extension HasApply {
    func apply(closure:(Self) -> ()) -> Self {
        closure(self)
        return self
    }
}

接下来让NSObject符合HasApply.

extension NSObject: HasApply { }

就这样

让我们测试一下

That's it

Let's test it

let button = UIButton().apply {
    $0.titleLabel?.text = "Tap me"
}

print(button.titleLabel?.text) // Optional("Tap me")

注意事项

我不会使用NSObject(这是Objective-C处理方式的一部分,我认为将来会在某些时候将其删除).我更喜欢像UIView这样的东西.

I wouldn't use NSObject (it's part of the Objective-C way of doing things and I assume it will be removed at some point in the future). I would prefer something like UIView instead.

extension UIView: HasApply { }

这篇关于如何在Swift中编写通用的apply()函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆