从 Swift 中的 max(_:_:) 看设计哲学

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看185 回复回复4 收藏收藏 分享淘帖 转播转播 分享分享 微信
查看: 185|回复: 4
收起左侧

从 Swift 中的 max(_:_:) 看设计哲学

[复制链接]
apper 发表于 2016-9-6 16:25:35 | 显示全部楼层 |阅读模式
快来登录
获取优质的苹果资讯内容
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
订阅梳理好了的知识点专辑

由于 Swift 不再支持宏了,于是 MAX,MIN 等一些列常用宏都被重写为 Swift 函数。我们来看看函数的定义:

[Swift] 纯文本查看 复制代码
@warn_unused_result
public func max<T : Comparable>(x: T, _ y: T) -> T  





1、warnunusedresult

先说说 @warnunusedresult 注解。 顾名思义,被该注解标记的方法所产生的返回值,如果未被使用,编译器会不开心哦(编译的时候会产生一条警告⚠️)。

这里讲一下方法的设计哲学。一般来说一个理想的带有返回值的方法,除了返回返回值以外,是不会产生任何其他副作用的。比如说不会改变入参的值(这也是 inout存在的原因) ,不会对系统的其他状态有影响(比如说不会改变类的实例变量的值)。这样的好处是减少方法产生的不确定性,同时方法使用的目的变得非常明确。

拿 max 来举例。max 方法被设计用来判断并返回两个参数中更大的那个。容易理解,当返回值没有被使用的时候,这次方法的调用也是没有意义的,因此 @warnunusedresult 的标注是非常合理的。

所以当你在开发 SDK 或是框架,甚至是和同事合作开发业务,同事会用到你的 API 的时候,你可以在需要的地方,用此注解来标记你的方法,以提示使用者注意使用方法产生的返回值。




2、面向协议

从方法的定义中,我们可以看到,传入的参数只要符合 Comparable 协议,就可以正确得到返回结果。

这意味着我们不仅可以用它来比较数字大小:

[Swift] 纯文本查看 复制代码
let maxInteger = max(10, 20)  


还可以用来比较 String 的大小:

[Swift] 纯文本查看 复制代码
let maxString = max("bc", "abc")  


甚至是自定义的对象,只要它实现了 Comparable 协议。从这一点上,我们可以窥见 Swift "面向协议编程" 的一斑。面向协议编程让 max(_:_: ) 从具体的类中解放出来,不关心入参是什么类,有什么结构,只关心 所传进来的参数能否被比较,而具体的比较则让入参自己去做,从而让 max(_:_: ) 具有普适性,达到程序设计上的低耦合。

这么说可能有点抽象,我们来举个具体的例子。

假设我们有这样的餐馆定义

[Swift] 纯文本查看 复制代码
struct Restaurant {  
    var area: Int // 占地面积
    var michelinRate: Int // 米其林等级
    var averageCoast: Int // 人均消费
    var name: String // 餐厅名称
    var logo: UIImage // 餐厅LOGO
}


如何比较两家餐馆谁大谁小?

按照餐馆面积比,平海路上的日料店表示不服;按照人均消费比,新白鹿表示不服;按照米其林等级比,一众特色小吃店表示不服;按照餐厅名称长度比,产品经理表示不服。

总地来说,"谁更大"其实是一种抽象的概念, max 方法不能也不该知道入参是如何比较的。只有入参自己知道自己该如何比较。因此抽象出 Comparable 协议是非常自然的。




3、Comparable

我们再来看看 Comparable 的定义

[Swift] 纯文本查看 复制代码
public protocol Comparable : Equatable {  
    /// over instances of `Self`.
    @warn_unused_result
    public func <(lhs: Self, rhs: Self) -> Bool
    @warn_unused_result
    public func <=(lhs: Self, rhs: Self) -> Bool
    @warn_unused_result
    public func >=(lhs: Self, rhs: Self) -> Bool
    @warn_unused_result
    public func >(lhs: Self, rhs: Self) -> Bool
}


Comparable 抽象了数学上严格全序的概念。虽然定义了五个方法(别忘了 Equatable 中还有一个 ==),但只需要实现 == 和 < ,其他方法只需要使用 Swift 标准库提供的默认实现,就可以根据严格全序定义推导出实现。

数学真是计算机科学的基石啊!

从 Swift 中的 max(_:_:) 看设计哲学

从 Swift 中的 max(_:_:) 看设计哲学 - 敏捷大拇指 - 从 Swift 中的 max(_:_:) 看设计哲学





作者:PPPan

都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。您的赞赏是我前进的方向。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

评分

参与人数 1金钱 +10 贡献 +10 专家分 +10 收起 理由
Anewczs + 10 + 10 + 10 32个赞!专家给力!

查看全部评分

本帖被以下淘专辑推荐:

数学家 发表于 2016-9-6 16:38:58 | 显示全部楼层
基本上可以用协议来实现所有数学算法啦
3rdev 发表于 2016-9-6 17:11:35 | 显示全部楼层
Swift 4.0 是不是还会重新支持宏?不然总感觉怪怪的
swifter 发表于 2016-9-7 16:08:00 | 显示全部楼层
Comparable 协议,那就还可以各种自定义协议
大秘小蜜 发表于 2016-12-23 02:02:39 | 显示全部楼层
厉害!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

淘帖专辑
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励
关闭

站长推荐 上一条 /1 下一条

热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表