Instance Methods are Curried Functions in Swift
An instance method in Swift is just a type method that takes the instance as an argument and returns a function which will then be applied to the instance.
I recently learned about a Swift feature that blew my mind a little. Instance methods are just curried functions that take the instance as the first argument. What’s a curried function, you ask?
The basic idea behind currying is that a function can be partially applied, meaning that some of its parameter values can be specified (bound) before the function is called. Partial function application yields a new function.
Example
Consider this simple example of a class that represents a bank account:
1 |
class BankAccount {
|
We can obviously create an instance of this class and call the deposit() method on that instance:
1 |
let account = BankAccount() |
So far, so simple. But we can also do this:
1 |
let depositor = BankAccount.deposit |
This is totally equivalent to the above. What’s going on here? We first assign the method to a variable. Pay attention to the lack of parentheses after BankAccount.deposit — we are not calling the method here (which would yield an error because you can’t call an instance method on the type), just referencing it, much like a function pointer in C. The second step is then to call the function stored in the depositor variable. Its type is as follows:
1 |
let depositor: BankAccount -> (Double) -> () |
In other words, this function has a single argument, a BankAccount instance, and returns another function. This latter function takes a Double and returns nothing. You should recognize the signature of the deposit() instance method in this second part.
I hope you can see that an instance method in Swift is simply a type method that takes the instance as an argument and returns a function which will then be applied to the instance. Of course, we can also do this in one line, which makes the relationship between type methods and instance methods even clearer:
1 |
BankAccount.deposit(account)(100) // balance is now 300 |
By passing the instance to BankAccount.deposit(), the instance gets bound to the function. In a second step, that function is then called with the other arguments. Pretty cool, eh?
Implementing Target-Action in Swift
Christoffer Lernö shows in a post on the developer forums how this characteristic of Swift’s type system can be used to implement the target-action pattern in pure Swift. In contrast to the common implementation in Cocoa, Christoffer’s solution does not rely on Objective-C’s dynamic message dispatch mechanism. And it comes with full type safety because it does not rely on selectors.
This pattern is often better than using plain closures for callbacks, especially when the receiving objects has to hold on to the closure for an indeterminate amount of time. Using closures often forces the caller of the API to do extra work to prevent strong reference cycles. With the target-action pattern, the object that provides the API can do the strong-weak dance internally, which leads to cleaner code on the calling side.
For example, a Control class using target-action might look like this in Swift (adopted from a dev forums post by Jens Jakob Jensen):
Update July 29, 2014: Made the action property in TargetActionWrapper non-optional. target must be optional because it is weak.
1 |
protocol TargetAction {
|
Usage:
1 |
class MyViewController {
|
Instance Methods are Curried Functions in Swift的更多相关文章
- Swift编程语言学习12 ——实例方法(Instance Methods)和类型方法(Type Methods)
方法是与某些特定类型相关联的函数.类.结构体.枚举都能够定义实例方法:实例方法为给定类型的实例封装了详细的任务与功能.类.结构体.枚举也能够定义类型方法:类型方法与类型本身相关联.类型方法与 Obje ...
- Mongoose 'static' methods vs. 'instance' methods
statics are the methods defined on the Model. methods are defined on the document (instance). We may ...
- UIView 实例方法 Instance Methods(转)
好了,我接着上篇,开始我们的对UIView 实例方法的探索 UIView 实例方法 Instance Methods 初始化一个视图 - (id)initWithFrame:(CGRect)aRect ...
- [Compose] 14. Build curried functions
We see what it means to curry a function, then walk through several examples of curried functions an ...
- Java SE 8 docs——Static Methods、Instance Methods、Abstract Methods、Concrete Methods和field
一.Static Methods.Instance Methods.Abstract Methods.Concrete Methods ——Static Methods:静态方法 ——Instance ...
- [Ramda] Convert Object Methods into Composable Functions with Ramda
In this lesson, we'll look at how we can use Ramda's invoker and constructNfunctions to take methods ...
- Static and Instance Methods in JavaScript
class.method/instance method https://abdulapopoola.com/2013/03/30/static-and-instance-methods-in-jav ...
- Android JNI 学习(八):Calling Instance Methods Api
一.GetMethodID jmethodIDGetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); 返回 ...
- Swift Standard Library: Documented and undocumented built-in functions in the Swift standard library – the complete list with all 74 functions
Swift has 74 built-in functions but only seven of them are documented in the Swift book (“The Swift ...
随机推荐
- MongoDb 抛出"Error retrieving nonce"异常
MongoDb在读取一个数据时抛出此异常, google之后也是只有源码没有任何相关结果, 考虑到之前同样的Db下不同的Collection没有发现此问题, 对比之后发现出错的url为: mongod ...
- 洛谷P4238 【模板】多项式求逆(NTT)
传送门 学习了一下大佬的->这里 已知多项式$A(x)$,若存在$A(x)B(x)\equiv 1\pmod{x^n}$ 则称$B(x)$为$A(x)$在模$x^n$下的逆元,记做$A^{-1} ...
- [題解]luogu_P3205/BZOJ_1996 合唱隊
前言:基本上發題解的都是抄的題解所以 來源:題解 题目描述 为了在即将到来的晚会上有更好的演出效果,作为AAA合唱队负责人的小A需要将合唱队的人根据他们的身高排出一个队形.假定合唱队一共N个人,第i个 ...
- ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) A
Our beloved detective, Sherlock is currently trying to catch a serial killer who kills a person each ...
- 在SpringBoot中用SpringAOP实现日志记录功能
背景: 我需要在一个SpringBoot的项目中的每个controller加入一个日志记录,记录关于请求的一些信息. 代码类似于: logger.info(request.getRequestUrl( ...
- D. Kay and Snowflake 树的重心
http://codeforces.com/contest/686/problem/D 给出q个询问,每次要求询问以x为根的子树中,哪一个点是重心. 树的重心:求以cur为根的子树的重心,就是要找一个 ...
- Mysql->order by SQL 根据多个条件排序
Mysql中根据多个条件排序:(各个条件间使用逗号隔开) 首先根据class_name字符串长短升序排列,然后根据开始时间降序排列: SELECT * FROM signup_class s OR ...
- Vue.js - Day5 - Webpack
在网页中会引用哪些常见的静态资源? JS .js .jsx .coffee .ts(TypeScript 类 C# 语言) CSS .css .less .sass .scss Images .jpg ...
- C/C++ 内存分配方式,堆区,栈区,new/delete/malloc/free
内存分配方式 内存分配方式有三种: [1] 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量, static 变量. [2] 在栈上创建.在执行函 ...
- java实现打开Windows控制台窗口
在写Python程序的时候突发奇想了一下,能不能用java代码实现打开控制台窗口呢? 经过查询网络资料和java API文档,终于实现了: package com.primeton.cmd; impo ...