我们在使用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. 我的Android进阶之旅------>解决Error:Unable to find method 'org.gradle.api.internal.project.ProjectInternal.g

    错误描述 今天在Github上面下载了一份代码,然后导入到Android Studio中直接报了如下图所示的错误: 错误描述如下: Error: Unable to find method 'org. ...

  2. JSONObject和JSONArray 以及Mybatis传入Map类型参数

    import org.json.JSONArray;import org.json.JSONObject; 将字符串转化为JSONArray   JSONArray  jsonArray = new ...

  3. java-序列化-001-原生介绍

    一.什么是对象序列化 java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长.但在现实应用中, ...

  4. 吴超老师课程--Hbase介绍和伪分布式安装

    1.HBase(NoSQL)的数据模型1.1 表(table),是存储管理数据的.1.2 行键(row key),类似于MySQL中的主键.     行键是HBase表天然自带的.1.3 列族(col ...

  5. delphi webbrowser 获取iframe

    procedure TForm1.Button4Click(Sender: TObject);var Index: Integer; Document: IHTMLDocument2; FrameId ...

  6. Python Tornado框架(TCP层)

    Tornado在TCP层里的工作机制 上一节是关于应用层的协议 HTTP,它依赖于传输层协议 TCP,例如服务器是如何绑定端口的?HTTP 服务器的 handle_stream 是在什么时候被调用的呢 ...

  7. 102. Binary Tree Level Order Traversal ------层序遍历

      Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to righ ...

  8. LightOJ - 1138 (二分+阶乘分解)

    题意:求阶乘尾部有Q(1 ≤ Q ≤ 108)个0的最小N 分析:如果给出N,然后求N!尾部0的个数的话,直接对N除5分解即可(因为尾部0肯定是由5*2构成,那么而在阶乘种,2的因子个数要比5少,所以 ...

  9. winform webbrowser禁用网页target=blank

    /// <summary> /// 屏蔽target=_blank 的弹出窗口 /// </summary> /// <param name="sender&q ...

  10. 菜单Menu

    <Menu HorizontalAlignment="> <MenuItem Header="文件"> <MenuItem Header=& ...