分享十条实用的Swift小提示

2020-01-09 00:14:44刘景俊

定义它们很简单,因为它们可以归入Appliance的子类,并符合CanCook


class Oven: Appliance, CanCook { }
class Microwave: Appliance, CanCook { }

Swift的existential可以支持使用它们。但除非你是认识某个大厨,不然你应该找不到一个大厨来你家做饭。类似的,除非你实在没办法,你也不会用一个吹风机做饭。

结果就是,这两个函数都不够好用——它们并没有完整描绘出我们想要接收的文件类型:


func makeDinner(using: Appliance) { }
func makeDinner(using: CanCook) { }

好在通过写Appliance & CanCook,Swift让我们能够把协议与子类合并到一个existential中。我们希望某些东西是日常工具(Appliance),并符合CanCook协议,就像这样:


func makeDinner(using: Appliance & CanCook) { }

2.协议扩展可以提供默认属性值

协议扩展为方法的执行提供了默认属性值,这些默认值之后可以被符合类型覆盖,但你也可以用它们为属性提供默认值。

下例中我们创建一个Fadeable协议,并在设定好的秒数后逐渐淡出:


protocol Fadeable {
 var fadeSpeed: TimeInterval { get }
 func fadeOut()
}

比起给所有符合类型添加各自的淡出速度和fadeOut()方法,我们可以在一个协议扩展中为它们提供默认值。


extension Fadeable where Self: UIView {
 var fadeSpeed: TimeInterval {
 return 1.0
 }
 
 func fadeOut() {
 UIView.animate(withDuration: fadeSpeed) {
  self.alpha = 0
 }
 }
}

这样你可以让新的子类符合它们,而不用担心重复写相同的默认值