Несмотря на то, что у Scala есть ключевое слово yield
, оно довольно сильно отличается от C # yield
, а Ruby's yield
отличается от обоих. Кажется, это ключевое слово с чрезмерным использованием. На первый взгляд использование yield
в C # выглядит очень ограниченным.
Чтобы сделать то же самое в Scala, вы можете определить свою собственную функцию высокого порядка. В английском это означает функцию, которая принимает функцию в качестве параметра.
Взять пример Microsoft , вот метод Scala:
object Powers {
def apply(number:Int, exponent:Int) (f:(Double) => Any) = {
(new Range(1,exponent+1,1)).map{exponent => f(Math.pow(number, exponent))}
}
}
Теперь у вас есть «итератор»:
scala> Powers(2,8){ println(_) }
2.0
4.0
8.0
16.0
32.0
64.0
128.0
256.0
Примечания:
Powers(2,8)
совпадает с Powers.apply(2,8)
. Это просто трюк с компилятором.
- Этот метод определяется двумя списками параметров, что может сбивать с толку. Это просто позволяет вам сделать:
Powers(2, 8){ println(_) }
вместо Powers(2, 8, {println(_)})
Scala: 1, C #: 0
Обновление:
Для вашего только что добавленного примера напишите traverse
, который выполняет обход, который вы хотите, не думая о том, как вы собираетесь его использовать. Затем добавьте дополнительный параметр, добавив (f(Node) => Any)
после списка параметров traverse
, например,
def traverse(node:Node, maxDepth:Int)(f(Node) => Any)) { ... }
В точке в traverse
, где у вас есть значение, которое вы бы yield
использовали в C #, позвоните f(yieldValue)
.
Если вы хотите использовать этот «итератор», вызовите traverse
и передайте ему функцию, которая делает то, что вы хотите сделать для каждого элемента в итераторе.
traverse(node, maxDepth) { (yieldValue) =>
// this is f(yieldValue) and will be called for each value that you call f with
println(yieldValue)
}
Это базовый случай «функционального программирования», и вы должны убедиться, что понимаете, что оно будет успешным в Scala.