Подтвердить что ты не робот

Scala синтаксис метода карты

Ниже приведен код http://www.scalaclass.com/book/export/html/1, чтобы сделать матричный точечный продукт.

Я не могу понять синтаксис между фигурными скобками.

  • Почему используются фигурные скобки, а не круглые скобки метода?
  • Это анонимный метод?
  • Что такое._1 и._2?

Спасибо.

type Row    = List[Double]
type Matrix = List[Row]

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ t:(Double, Double) => t._1 * t._2 }.reduceLeft(_ + _)
4b9b3361

Ответ 1

  • Почему используются фигурные скобки, а не круглые скобки метода?

Некоторые люди предпочитают использовать фигурные скобки, когда параметр является анонимной функцией. С одной стороны, фигурные скобки позволяют сопоставлять анонимные функции, а в скобках - нет. В этом конкретном примере нет необходимости в фигурных скобках.

Вот пример, где требуются фигурные скобки (из-за соответствия шаблона case):

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ case (a, b) => a * b }.reduceLeft(_ + _)

Обратите внимание, что вышеприведенная функция выполняет то же самое, что и вопрос в вопросе, несколько иначе.

  • Есть ли t анонимный метод?

Нет, это параметр. Точно так же, как v1 и v2 являются параметрами для dotProd, t является параметром для анонимной функции, передаваемой в map.

  • Что такое ._1 и ._2?

Методы на t. Параметр t был определен как кортеж (в частности, Tuple2[Double, Double], который может быть записан как (Double, Double)), а кортежи позволяют извлекать каждый член кортежа с помощью таких методов: _1, _2, _3 и т.д.

A Tuple2 имеет только _1 и _2, конечно. Обратите внимание, что первый параметр _1, а не _0, из-за влияния других функциональных языков.

В любом случае метод zip преобразует Row (List[Double]) в List[(Double, Double)]. Метод map принимает функцию, которая преобразует элементы списка (которые являются (Double, Double) кортежами) во что-то другое.

Ответ 2

В этом конкретном случае фигурные скобки не имеют преимущества по сравнению с простым старым синтаксисом, но в целом сладкая вещь об использовании фигурных скобок заключается в том, что они позволяют писать выражения, соответствующие шаблону внутри map ...:

поэтому я могу переписать этот

.map{ t:(Double, Double) => t._1 * t._2 }

в этот

.map{ case(a: Double, b: Double) => a*b }

но это не скомпилируется:

.map( case(a: Double, b: Double) => a*b )

._ 1,._2 предоставляет доступ к первому, второму,... N-элементу N-кортежа, как сказал Ли.

Ответ 3

Вы можете найти очень хороший ответ на различия между фигурными скобками {} и круглыми скобками() в этом вопросе: Какая формальная разница в Scala между фигурными скобками и скобками и когда они должны использоваться?

Для _1, _2 см. Значение знака _2 в Scala языке.

И да, t:(Double, Double) => t._1 * t._2 - анонимная функция (фактически не метод). Разница между методом и функцией в Scala

Ответ 4

Кудрявые скобки обозначают анонимную функцию с типом Tuple2[Double,Double] => Double. Аргументу дается локальное имя t, поэтому t является кортежем из двух двухлокальных. t._1 относится к первому элементу и t._2 второй.

Следовательно, map дает список элементарных произведений компонентов двух векторов, а reduceLeft суммирует эти произведения для вычисления точечного произведения.