【问题标题】:Can't understand Scala example无法理解 Scala 示例
【发布时间】:2017-08-09 08:55:18
【问题描述】:

我很难理解 Scala 的基础知识,尤其是 this 代码:

trait RichIterator extends AbsIterator {
  def foreach(f: T => Unit): Unit = while (hasNext) f(next())
}

对我来说,foreach 看起来像一个返回单位的方法。它接受一个函数,f作为参数:

f: T => Unit

它也返回单位。该方法在 hasNext 为 true 时循环,我不知道 f(next()) 做了什么。这是 f 输入参数吗?为什么要使用似乎只返回一个单位的函数?有人可以帮我解释一下吗。

【问题讨论】:

    标签: scala


    【解决方案1】:

    foreach 函数通常用于实现副作用。我的意思是,当我调用 List(1, 2, 3).foreach(println) 时,我想打印(这是一个副作用)列表中的所有元素。

    我不知道 f(next()) 做了什么。

    f(next()) 表示调用函数 f - 这是 foreach 函数的参数 - 使用下一个元素 - 通过调用 next() 检索。

    为什么要使用只返回 Unit 的函数?

    通常在 Scala 中,您会注意到具有副作用的方法返回 Unit。我实际上是从 TraversableLike 中找到的 foreach 的原始定义中提取了一段 scaladoc。

    /**
     *  @param  f   the function that is applied for its side-effect to every element. The result of function `f` is discarded.
     *  @tparam  U  the type parameter describing the result of function `f`. This result will always be ignored. Typically `U` is `Unit`, but this is not necessary.
     */
    def foreach[U](f: A => U): Unit
    

    考虑到 foreach 的结果将始终被忽略,可以直接将其设置为 Unit,而不是像示例的作者那样强制执行另一个类型参数。

    希望对你有帮助:)

    【讨论】:

    • 谢谢,你能解释一下 A => U 究竟做了什么吗?它似乎没有做任何事情,为什么有必要?
    • 还有什么是[U]?
    • A => U 是从泛型类型 A 到泛型类型 U 的函数参数。[U] 是参数化 foreach 方法的泛型类型。正如文档所说 - 通常 UUnit 但这不是必需的 - 它只是为了允许对 foreach 函数进行更通用的定义,仅此而已:)
    • 谢谢,所以函数只是将类型从 A 更改为 U?何必?为什么方括号中的 [U] 不在带有 f: A => U 的 '( )' 中?
    • 方括号解释here
    【解决方案2】:

    在本例中,正如您正确注意到的那样,foreach 函数循环遍历所有元素(使用 while 和 hasNext)。

    f 是你作为参数得到的函数。

    您使用所有元素元素调用此函数(通过在循环中调用 next() 获得)。

    所以函数 f 对每个元素都执行。

    示例: 你传递函数println。 现在循环遍历迭代器的每个元素。使用next(),您将获得下一个元素。这将传递给您的 println 函数(您作为参数提供)。因此,每个元素都会被打印出来。

    【讨论】:

      【解决方案3】:

      Foreach 是一个循环,它对包裹在对象中的每个元素执行一些操作。在这个例子中,它扩展了 AbsIterator,所以 next() 是可迭代序列的下一个元素。您通过传递参数函数来使用 foreach,该函数将对每个元素执行一些操作,但不会像 map 那样更改它,并且不像 map 它不会返回新集合,这就是它是 UNIT 的原因。简单的例子是如果 RichIterator 将迭代字符串。

      然后你可以像这样拥有 Iterable: ("1","2","3")

      您可以通过传递 f = (str => println(str)) 对此使用 foreach

      然后就可以了

      hasNext -> true
      println("1")
      hasNext -> true
      println("2")
      hasNext -> true
      println("3")
      hasNext -> false
      

      而且输出很简单

      1
      2
      3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-14
        • 1970-01-01
        • 1970-01-01
        • 2018-05-07
        • 2015-03-24
        • 2011-09-27
        • 2023-04-09
        • 1970-01-01
        相关资源
        最近更新 更多