加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在Scala中编写函数的以下方法有什么区别?

发布时间:2020-12-16 09:09:30 所属栏目:安全 来源:网络整理
导读:我是 Scala的新手,已经看到很多方法来定义一个函数,但是找不到关于差异的明确解释,以及何时使用哪个表单. 以下函数定义之间的主要区别是什么? 使用’=’ def func1(node: scala.xml.Node) = { print(node.label + " = " + node.text + ",")} 没有’=’ def
我是 Scala的新手,已经看到很多方法来定义一个函数,但是找不到关于差异的明确解释,以及何时使用哪个表单.

以下函数定义之间的主要区别是什么?

>使用’=’

def func1(node: scala.xml.Node) = {
    print(node.label + " = " + node.text + ",")
}

>没有’=’

def func2 (node: scala.xml.Node) {
    print(node.label + " = " + node.text + ",")
}

>使用’=>’

def func3 = (node: scala.xml.Node) => {
    print(node.label + " = " + node.text + ",")
}

>作为变种

var func4 = (node: scala.xml.Node) => {
    print(node.label + " = " + node.text + ",")
}

>没有障碍

def func5 (node: scala.xml.Node) = print(node.label + " = " + node.text + ",")

当用作回调时,它们似乎都编译并呈现相同的结果

xmlNodes.iterator.foreach(...)

>每个生成的字节码有什么不同吗?
>使用哪种表格时是否有任何指导?

解决方法

这些问题中的每一个问题都已在本网站的其他地方得到解答,但我认为没有任何问题可以解决这些问题.所以:

大括号和平等

使用等号定义的方法返回一个值(无论最后评估的是什么).仅使用大括号返回的方法返回Unit.如果你使用等于但最后的东西对单位进行评估,则没有区别.如果它是等号后的单个语句,则不需要括号;这对字节码没有影响.所以1.,2.,和5.基本相同:

def f1(s: String) = { println(s) }     // println returns `Unit`
def f2(s: String) { println(s) }       // `Unit` return again
def f5(s: String) = println(s)         // Don't need braces; there's only one statement

功能与方法

一个函数,通常写成A => B,是一个Function类的子类,例如功能1 [A,B].因为这个类有一个apply方法,当你只使用没有方法名称的parens时Scala神奇地调用它,它看起来像一个方法调用 – 它是,除了它是对该Function对象的调用!所以,如果你写

def f3 = (s: String) => println(s)

那么你所说的是“f3应该创建一个Function1 [String,Unit]的实例,它有一个看起来像def apply(s:String)= println(s)”的apply方法.所以如果你说f3(“Hi”),这首先调用f3来创建函数对象,然后调用apply方法.

每次想要使用它时创建函数对象都相当浪费,因此将函数对象存储在var中会更有意义:

val f4 = (s: String) => println(s)

这包含def(方法)将返回的同一函数对象的一个??实例,因此您不必每次都重新创建它.

什么时候用

人们的惯例有所不同:单位= ……和{}.就个人而言,我编写了所有返回Unit而没有等号的方法 – 这表明该方法几乎肯定无用,除非它有某种副作用(改变变量,执行IO等).此外,我通常只在需要时使用大括号,因为有多个语句或因为单个语句太复杂我想要一个视觉辅助来告诉我它的结束位置.

应该随时使用方法,一个方法.只要您想要将函数对象传递给其他方法来使用它们,就应该创建函数对象(或者在您希望能够应用函数时将其指定为参数).例如,假设您希望能够缩放值:

class Scalable(d: Double) {
  def scale(/* What goes here? */) = ...
}

你可以提供一个常数乘数.或者你可以提供一些东西来增加和一些东西.但最灵活的是,你只需要从Double到Double的任意函数:

def scale(f: Double => Double) = f(d)

现在,也许您已经了解了默认比例.这可能根本没有扩展.所以你可能想要一个带Double的函数并返回相同的Double.

val unscaled = (d: Double) => d

我们将函数存储在val中,因为我们不想一遍又一遍地创建它.现在我们可以使用此函数作为默认参数:

class Scalable(d: Double) {
  val unscaled = (d: Double) => d
  def scale(f: Double => Double = unscaled) = f(d)
}

现在我们可以调用x.scale和x.scale(_ * 2)和x.scale(math.sqrt),它们都可以工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读