`
1025250620
  • 浏览: 225854 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Scala 中apply方法的用法~(转)

阅读更多

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 的取值操作,的确如此。我们可以作个例子:

1
2
3
4
5
6
7
8
9
class SomeClass {
    def apply(key: String): String = {
        println("apply method called, key is: " + key)
        "Hello World!"
    }
}
 
val anyObject = new SomeClass
println(anyObject("key1"))

执行后输出结果是:

apply method called, key is: key1
Hello World!

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

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

1
val numNames = Array("zero", "one", "two")

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

1
val numNames = Array.apply("zero", "one", "two")

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

1
2
3
4
5
6
7
8
9
object EMail {
    def apply(user: String, domain: String): String = {
        println("apply method called")
        user + "@" + domain
    }
}
 
val email = EMail("fantasia", "sina.com")
println(email)

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

apply method called
fantasia@sina.com

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

1
greetStrings(0) = "Hello"

会转换成调用

1
greetStrings.update(0, "Hello")

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

01
02
03
04
05
06
07
08
09
10
class SomeClass {
    def update(arg1: Int, arg2: String, arg3: String): String = {
        println("update method called")
        arg1 + "|" + arg2 + "|" + arg3
    }
}
 
val obj = new SomeClass
val result = (obj(1, "key1") = "Hello")
println(result)

执行后输出结果为:

update method called
1|key1|Hello

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

因为这样的行为,apply 方法又被称为注入方法,因为它可以传入一些参数并生成指定子集的元素。在以后的学习中会遇到它对偶的方法 unapply,被称为抽取方法,因为它可以传入相同子集的元素并抽取其中的部分,这是后话。

分享到:
评论

相关推荐

    Scala—— 9.伴生对象apply方法

    在伴生对象中定义apply方法,可以实现:类名(参数)方式来创建对象实例 object boke_demo01 { def main(args: Array[String]): Unit = { val list = List(1, 2, 5) println(list) val pig = new Pig(狗蛋) //...

    scala从入门到精通技术教学视频

    15.apply()方法 16.案例_定义工具类 第七章 继承 00.导学 01.继承入门 02.单例对象的继承 03.方法重写 04.isInstanceOf和asInstanceOf 05.getClass和ClassOf关键字 06.抽象类入门 07.抽象字段 08.匿名...

    快学 scala 中文版 带完整目录

    1.6 apply方法 9 1.7 Scaladoc 11 练习 16 第2章 控制结构和函数 A1 19 2.1 条件表达式 20 2.2 语句终止 22 2.3 块表达式和赋值 22 2.4 输入和输出 23 2.5 循环 25 2.6 高级for循环 27 2.7 函数 28 2.8 ...

    Scala 使用IDEA开发

    进入IDEA,安装Scala插件,或者自己导入插件 方法1: 方法2: 4.点击 ok->apply -> 重启 idea 即可 开发 步骤 1:file->new project -> 选择 maven 步骤 2. 步骤 3. 步骤 4:默认下,maven 不支持 scala 的开发...

    try:尝试成功失败Scala API for Java的实现

    为了使用Try您需要调用Try.apply(FailableSupplier)方法,该方法提供一个lambda,该lambda具有与常见java.util.function.Supplier相同的签名。 实际上, FailableSupplier只是一个java.util.function.Supplier ,在...

    scalaflavor4j:Scala 风格的 Java 中有用的 API

    ScalaFlavor4J ScalaFlavor4J 在 Java 中为您提供了 Scala 风格的..._(xxx)方法已被删除,因为该名称在 Java 8 中已弃用。请改用apply(xxx) 。 由于 JSR-335 规范, FunctionN从抽象类更改为接口。 如果你想使用co

    eithervalidation_2.9.2-1.0.1.zip

    eithervalidation.zip,验证是使用scala标准作为应用函子的一种简单方法,不使用scalaz,通过apply方法

    imp:宏,用于调用隐式值

    在Scala中创建类型类时有一个约定,以在伴随对象上提供apply方法,以访问隐式类型类实例。 这里可以使用summon宏来创建此方法的更有效形式。 ([1]通过上下文绑定,我的意思是将类型参数声明为[A: Magma] ,它也与...

    EsperantoWordSegmenter

    用法 scala WordSegmenter.WordSegmenter trainingFile morphemesByTypeDirectory [-m|r|n|b|t]有关示例用法,请参见experiments / run_tests.sh选项 Default: apply rules, use unigram Markov model -m: Use ...

    s3_website:管理S3网站:同步,通过CloudFront交付,受益于高级S3网站功能

    )用法这是您的入门方法: 创建对S3具有足够权限的API凭据。 更多信息。 转到您的网站目录运行s3_website cfg create 。 这将生成一个名为s3_website.yml的配置文件。 将您的AWS凭证和S3存储桶名称放入文件中运行s3_...

    Python yield 使用浅析

    本文将由浅入深地讲解 yield 的概念和用法,帮助读者体会 Python 里 yield 简单而强大的功能。 您可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ? 我们先抛开 generator...

Global site tag (gtag.js) - Google Analytics