Scala概述(四)操作也是对象(2、3)

4.2.    函数也是对象(Functions are Objects

既然方法是值,值是对象,方法当然也就是对象。实际上,函数类型和函数值(注意:指函数本身作为值——译注)只不过是相应的类及其实例的语法糖衣。函数类型S=>T等价于参数化类型scala.Function1[S, T],这个类型定义在Scala标准类库中:

package scala

abstract class Function1[-S,+T] {

def apply(x: S): T

}

       参数超过一个的函数也可类似地定义,一般而言,n-元函数类型:(T1T2Tn=>T被解释为Functionn[T1T2TnT]。也就是说,函数就是拥有apply方法的对象。例如,匿名函数“+1:x:int=>x+1,就是如下函数Function1的实例:

new Function1[int, int] {

def apply(x: int): int = x + 1

}

反之,当一个函数类型的值被应用于参数之上(也就是调用——译注)时,这个类型的apply方法被自动插入,例如:对于Function1[S, T]类型的函数pp(x)调用自然扩展为p.apply(x)

 

4.3. 细化函数(Refining Functions

既然Scala中函数类型是类,那么也可以再细化成为子类。以Array为例,这是一种以整数为定义域的特殊函数。Array[T]继承自Function1[int, T],并添加了数组更新、长度等方法:

package scala

class Array[T] extends Function1[int, T]

with Seq[T] {

def apply(index: int): T = ...

def update(index: int, elem: T): unit= ...

def length: int = ...

def exists(p: T => boolean): boolean = ...

def forall(p: T => boolean): boolean = ...

...

}

赋值语句左侧的函数调用是存在特殊语法的,他们使用update方法。例如,a(i)=a(i)+1被翻译成:

a.update(i, a.apply(i) + 1)

Array存取翻译成方法调用看上去代价比较高,但是Scala中的inlining变换可以将类似于上面的代码翻译成宿主系统的原生数组存取。

上述Array类型还定义了existsforall方法,这样也就不必手工定义了,使用这些方法,hasZeroRow可以如下定义:

def hasZeroRow(matrix: Array[Array[int]]) =

matrix exists (row => row forall (0 ==))

注意上述代码和相关操作的语言描述的对应性:“test whether in the matrix there exists a row such that in the row all elements are zeroes”(检测一个矩阵,看看它是否有一行的所有元素都等于0。这里保留英语原文,因为原文中使用斜体部分对应于上述代码的内容,体现两种语法的对应关系——译注)。还要注意一点:在上面的匿名方法中,我们略去了参数row的类型,因为其类型可以被Scala编译器根据matrix.exists方法推断出来。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值