Scala 中的 apply 和 update 方法

Scala 是构建在 JVM 上的静态类型的脚本语言,而脚本语言总是会有些约定来增强灵活性。灵活性可以让掌握了它的人如鱼得水,也会让初学者不知所措。比如说 Scala 为配合 DSL 在方法调用时有这么一条约定:

在明确了方法调用的接收者的情况下,若方法只有一个参数时,调用的时候就可以省略点及括号。如 “0 to 2”,实际完整调用是 “0.to(2)”。但 “println(2)” 不能写成 “println 10“”,因为未写出方法调用的接收者 Console,所以可以写成 “Console println 10”

到这里就要讲到 apply 和 update 方法相关的约定,描述的是直接在变量(对象)后直接加圆括号的代码的情况下,那就是:

用括号传递给变量(对象)一个或多个参数时,Scala 会把它转换成对 apply 方法的调用;与此相似的,当对带有括号并包括一到若干参数的进行赋值时,编译器将使用对象的 update 方法对“括号里的参数和等号右边的值”执行调用。

对上面那段话的解释可由下面几个例子得到很好的理解

1. theArray(0), 取数组的第一个元素的操作会转换成 theArray.apply(0) 操作,这也能解释为什么 Scala 数组取值不用中括号括下标的方式,因为它也是一次方法调用

2. anyObject("key1") 会被转换成 anyObject.apply("key") 操作,这也会让我们想到 Map 的取值操作,的确如此。我们可以作个例子:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. classSomeClass {  
  2.     defapply(key:String):String ={  
  3.         println("apply method called, key is: " + key)  
  4.         "Hello World!"  
  5.     }  
  6. }  
  7.    
  8. valanyObject =new SomeClass  
  9. println(anyObject("key1"))  

执行后输出结果是:

apply method called, key is: key1
Hello World!

说明是调用到了相应的 apply 方法的。

3. 我们在构造 Array 或  Map 时,会简单的写成

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. valnumNames =Array("zero","one","two")  

这里也是调用的 apply 方法,我们看起来好像是作用在类 Array 上的,其实不然,而是作用在 Array 的伴生对象(object Array)上的,调用的是伴生对象 Array 的  apply 方法,即:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. valnumNames =Array.apply("zero","one","two")  

上面的功效像是调用的 Array 类的 apply 工厂方法。同样看个单例对象的例子,也解释了伴生对象的 apply 方法的调用

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. objectEMail {  
  2.     defapply(user:String, domain:String):String ={  
  3.         println("apply method called")  
  4.         user + "@"+ domain  
  5.     }  
  6. }  
  7.    
  8. valemail =EMail("lyrebing","hotmail.com")  
  9. println(email)  

上面代码执行后输出结果是:

apply method called
lyrebing@hotmail.com

有了前面 apply 方法的理解,下面对 update 方法的理解就很顺畅了,比如:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. greetStrings(0)="Hello"  

会转换成调用

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. greetStrings.update(0,"Hello")  

来个复杂的 Demo,赋值时等号左边带两个参数,并且赋值操作会产生返回值的情况(纯粹用于演示)

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. classSomeClass {  
  2.     defupdate(arg1:Int, arg2:String, arg3:String):String ={  
  3.         println("update method called")  
  4.         arg1+ "|"+ arg2+ "|"+ arg3  
  5.     }  
  6. }  
  7.    
  8. valobj =new SomeClass  
  9. valresult =(obj(1,"key1")="Hello")  
  10. println(result)  

执行后输出结果为:

update method called
1|key1|Hello

在应用 apply 和 update 规则时,关键是转换后的调用要找到相应的方法原型。再就是应用 update 时,等号右边的值会作为 update 方法的最后一个参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Scala,函数(function)和方法(method)是有一些区别的。 1. 定义方式:函数是通过`val`关键字定义的值,而方法是通过`def`关键字定义的类成员。 2. 形式:函数是一个独立的值,可以直接赋值给变量,作为参数传递给其他函数,或者作为返回值返回。方法则是属于类或对象的成员,需要通过实例或者类名来调用。 3. 参数列表:函数的参数列表可以用括号包裹,也可以省略括号。方法的参数列表总是需要用括号包裹。 4. 调用方式:函数可以直接使用参数列表调用,而方法需要通过对象或者类名来调用。 5. 带有副作用:函数通常是纯函数(pure function),即没有副作用的函数。方法可以有副作用,例如修改对象的状态或者打印输出等。 下面是一个示例来说明函数和方法的区别: ```scala // 定义函数 val add: (Int, Int) => Int = (x, y) => x + y // 定义类,并定义一个方法 class MyClass { def multiply(x: Int, y: Int): Int = x * y } // 创建类的实例 val obj = new MyClass() // 调用函数 val result1 = add(3, 4) println(result1) // 输出: 7 // 调用方法 val result2 = obj.multiply(3, 4) println(result2) // 输出: 12 ``` 需要注意的是,Scala方法可以转换为函数,而函数不能直接转换为方法。可以使用方法引用(method reference)或者使用下划线(_)来将方法转换为函数。例如: ```scala val multiplyFunc: (Int, Int) => Int = obj.multiply val multiplyFunc2: (Int, Int) => Int = obj.multiply _ ``` 总的来说,函数和方法Scala有些许的差异,但在实际使用,它们可以互相转换和配合使用,根据需要选择合适的方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值