我们在使用scala的时候经常会用到对象的apply方法和update方法。

虽然我们表面没有察觉,但是实际上两个方法都会遵循相关约定被调用。

apply

apply方法的约定:用括号传递给变量(对象)一个或多个参数的时候,会把它转换成对apply方法的调用。

我们先看一个例子。

class ClassApplyTest{  //类的apply方法调用示例
def apply(param:String): String ={
println("apply method called,the paramter is "+param);
"Hello,world";//返回值
}
}
object Main{
def main(args:Array[String]): Unit ={
val myApply = new ApplyTest;//实例化ApplyTest
println(myApply("param1"));//传入参数param1
}
}
输出结果 apply method called,the paramter is param1 Hello,world

我们从上个例子看到,我们给ApplyTest类实例一个对象myApply,然后给myapply传入了param1的参数。

过程中并没有调用对象的apply方法,myapply对象自己调用了apply方法。

我们再看一个例子

object SingleObjectApplyTest{//单例对象的apply方法调用示例
def apply(param1:String,param2:String):String = {
println("apply method called");
param1+" and "+param2;
}
def main(args:Array[String]): Unit ={
val myApply = SingleObjectApplyTest("zyh","zqy");
    //注意,我们这里建的是单例对象不是类,并不用new关键字。
println(myApply);
}
}
输出结果 apply method called zyh and zqy

我们定义了一个单例对象,并在对象中定义了apply方法。

当我们建立单例对象并传参的时候自动调用了apply方法返回了param1 and param2到了myApply。

class ClassAndObjectApplyTest{ //伴生类和对象apply方法的结合使用
}
class ApplyTest{
def apply()={
println("apply method in class is called.");
}
def greetingFromClass = println("Greet method is called.");
//没有参数的时候可以省略圆括号
}
object ApplyTest{
def apply() = {
println("apply method in object is called.");
new ApplyTest;//返回一个ApplyTest类型的实例
}
}
object ClassAndObjectApplyTest{
def main(args:Array[String]): Unit ={
val myApply = ApplyTest();//ApplyTest伴生对象的调用,这里的括号一定不能省略
//注意,我们这里没有new关键字,是对ApplyTest的伴生对象的调用
//伴生对象会自动调用伴生对象的apply方法
myApply.greetingFromClass;
myApply();
//ApplyTest伴生类的调用
//然后自动调用了伴生类的apply方法
}
}
输出结果 apply method in object is called. Greet method is called. apply method in class is called.

我们这个例子包含了两对的伴生类和对象。

因为我们这里并没有任何参数,所以我们这里使用()就是向其传入参数。

我们在调用ApplyTest伴生对象并传参的时候,自动调用了ApplyTest伴生对象的apply方法,返回一个ApplyTest伴生类的一个实例对象。

我们可以通过ApplyTest伴生类的对象访问类中的方法,虽然被实例化了但是并没有传递参数,所以并没有调用其apply方法。

当我们执行myApply()的时候是对ApplyTest伴生类传参的操作,因为没有参数,所以只加了圆括号,然后自动调用其apply方法。

下面看一个scala语法中的apply的例子

val myStrArr = Array("BigDate","Hadoop","Spark");

注意到,我们在定义数组的时候,并没有像Java那样需要使用new关键字创建,

没有new实例,并不能用构造器创建,而且还直接传递了三个参数,怎么创建的呢?

其实这里,scala就会自动转换成对Array的伴生对象apply方法的调用,完成数组的建立和初始化。

update

update方法的约定:当对带有圆括号并包括一到若干参数的对象进行赋值时,编译器将调用对象的update方法。

在调用时,是把括号里的参数和等号右边的对象一起作为方法的输入参数来执行调用。

示例

val myStrArr = new Array[String](3);//声明一个长度为3的字符串数组
myStrArr(0) = "BigDate";//这里正好符合了update方法的调用规则
//调用了伴生类的Array的update方法
            //执行了myStrArr.update(0,"BigDate")

从上个例子可以看出,在进行数组赋值的时候,之所以没有向java一样采用了myStrArr[0]这样的赋值的方式,

而是采用了update方法的赋值机制,为了能触发update方法的机制,所以才使用myStrArr(0)这样圆括号的形式进行赋值。

【scala】apply和update的更多相关文章

  1. Scala 中的 apply 和 update 方法[转]

    原文链接:http://blog.csdn.net/lyrebing/article/details/21696581 Scala 是构建在 JVM 上的静态类型的脚本语言,而脚本语言总是会有些约定来 ...

  2. (转)scala apply方法 笔记

    在akka源码中有这样一个Cluster类. 使用方法是这样的:val cluster = Cluster(context.system); 作为scala菜鸟的我,并没有找到Cluster(syst ...

  3. Scala Apply

    class ApplyTest{ //一定要写(),不加括号就报错. def apply() = println("Into Spark!") def havaAtry(){ pr ...

  4. 抹掉Scala的糖衣(14) -- Update Method

    欢迎关注我的新博客地址:http://cuipengfei.me/ 在Scala中,名字叫做update的方法是有特殊作用的. 比如: 1 2 3 val scores = new scala.col ...

  5. Scala 具体的并行集合库【翻译】

    原文地址 本文内容 并行数组(Parallel Array) 并行向量(Parallel Vector) 并行范围(Parallel Range) 并行哈希表(Parallel Hash Tables ...

  6. scala学习笔记——操作符

    中置操作符(二元操作符),操作符位于两个参数之间.操作符包括字母,比如to,也可以包括操作符字符,比如1->10,等同于方法调用1.->(10) a 标识符 b 其中的标识符是一个带有两个 ...

  7. Scala入门指南与建议

    最近在学习使用Scala语言做项目,感觉这门语言实在是太优美了!作为一个本科数学.研究生机器学习专业的混合人才(哈哈),这门语言真的是满足了普通计算机编程(告诉计算机怎么做)和函数式编程(告诉计算机做 ...

  8. scala流程控制语句以及方法和函数

    1.if else表达式 scala中没有三目运算符,因为根本不需要.scala中if else表达式是有返回值的,如果if或者else返回的类型不一样,就返回Any类型(所有类型的公共超类型). 例 ...

  9. scala学习手记37 - 容器的使用

    这次统一看一下scala中容器类的几个方法. Set filter()方法 filter()方法用来从Set中过滤获取含有指定特征的元素.示例代码如下: val colors1 = Set(" ...

随机推荐

  1. GTID的主从复制的配置

    主库配置: (一).修改配置文件:在my.cnf配置文件中开启如下选项. [mysqld] #GTID: gtid_mode=on enforce_gtid_consistency=on server ...

  2. MongoRepository动态代理及jpa方法解析源码分析

    public interface FzkRepository extends MongoRepository<Fzk, String> { Fzk findByName(String na ...

  3. HDU4631(标程代码)

    /*将x从小到大排序,每次插入一个点,直接找比这个点的x大的第一个,然后从这个开始向两边找 ,找点的下标用多重容器实现*/ #include<stdio.h> #include<st ...

  4. 【JavaScript】写代码前的准备

    1.搭建开发环境,编辑器推荐HBuilder,浏览器用谷歌. 2.编写一个HelloWorld程序. HelloWorld.html <!DOCTYPE html> <html> ...

  5. Tomcat 启动内存修改

    内存修改文件 Windows 文件 /bin/catalina.bat Linux 文件 /bin/catalina.sh 方法一 # 设置参数 JAVA_OPTS='-Xms[初始化内存大小] -X ...

  6. article嵌套

    例如: 为了将每一个部分都突出显示,可以将article添加边框和颜色的属性: <style> article{ border: 1px solid #ff0000; margin: 5p ...

  7. ssi include返回404页面

    项目中index.html中包含<!--#include virtual="/commonfrag/djdzkan/recomm_www_info.inc"  --> ...

  8. 20145219 《Java程序设计》第08周学习总结

    20145219 <Java程序设计>第08周学习总结 教材学习内容总结 通用API 日志API 1.java.util.logging包提供了日志功能相关类与接口,使用日志的起点是log ...

  9. C++中的内存区[译文]

    C++ 中的内存区 Const Data: The const data area stores string literals and other data whose values are kno ...

  10. 如何实现一个简单的RPC

    在如何给老婆解释什么是RPC中,我们讨论了RPC的实现思路. 那么这一次,就让我们通过代码来实现一个简单的RPC吧! RPC的实现原理 正如上一讲所说,RPC主要是为了解决的两个问题: 解决分布式系统 ...