Scala и объект::

Я нырял в скалу, и до сих пор мне это очень нравится. Я перехожу к сопоставлению с образцом и кейсам, и следующее несколько озадачило меня. Я знаю, что он делает, но я хочу точно понять, что происходит

var list = List(2,3,4)
1::list

Если я прав в моем понимании до сих пор. Затем:: представляет объект case. Если так, то мой вопрос:

как я "оставил заявку" на 1? вместо того, чтобы:: быть методом 1. По сути, кто-то может несколько отделить это утверждение 1:: list, показывая, что на самом деле происходит (т.е. какие методы вызываются для какого объекта)

Спасибо

5 ответов

Решение

Раздражает, что некоторые из самых заметных и удивительных особенностей Scala имеют такую ​​сложность прямо под поверхностью. Итак, рассмотрим эту простую строку:

val (head :: tail): ::[Int] = 1 :: Nil

Каждое из трех мест, где :: Похоже, относится к другому ::и другой механизм в Scala. Давайте рассмотрим каждый из них по порядку.

head :: tail

То, что здесь происходит, - это сопоставление с образцом, точно так же, как case заявления. Сопоставление с образцом может появиться на val назначения, на левой стороне <- в for понимание и на case заявления.

Итак, как происходит это конкретное сопоставление с образцом? Хорошо, когда шаблон в формате a b cСкала переводит это в b(a, c), который затем переводится в призывы к unapply или же unapplySeq на объекте b,

Так, :: в val (head :: tail) относится к объекту :: (определяется через case class).

: ::[Int]

Это объявление типа, так ::[Int] это тип. :: сам по себе является классом, а также конструктором типов (поскольку он создает типы с помощью параметра типа - ::[Int] это один тип, ::[String] другой тип и т. д.). Это также подкласс List, который имеет только два подкласса: :: и синглтон класс Nil,

Эта декларация является излишней, и, вообще говоря, вряд ли когда-либо используется :: как тип или класс. Я показываю это здесь в основном для полноты.

1 :: Nil

Вот, :: это метод. Это метод Listтак, так как Nil это List а также 1 нет, он должен принадлежать Nil (или быть доступным через неявное преобразование).

Механизм примечания здесь заключается в том, что методы, заканчивающиеся на :, когда используется в нотации инфиксного оператора, связывается справа, а не слева. Или, другими словами, a :: b эквивалентно b.::(a),

Этот механизм используется редко и, как я подозреваю, сделан в основном для того, чтобы сделать традиционные алгоритмы списка fp более знакомыми программистам, использующим fp. Он используется в нескольких других местах стандартной библиотеки Scala и за ее пределами.

На Scala 2.8, например, теперь есть +:, которая служит той же цели ::, но определяется для всех Seq, Это отражено :+, который добавляет элементы, и чей : не служит никакой иной цели, кроме устранения неоднозначности +, который перегружен для объединения строк.

Имя оператора, оканчивающееся на : связывает вправо. :: [A] действительно case class и подкласс List[A], как видно из справочника по Scala API. :: также метод, работающий со своим правым аргументом, списком, принимающим левый операнд в качестве аргумента и возвращающим ::[A],

Итак, в вашем примере, метод :: называется на list с 1 в качестве аргумента. Это создает объект типа :: [Int] с аргументами 1 а также list,

Очень быстрый ответ. Метод:: вызывается из списка с параметром 1.

Любое имя метода (и да,:: это метод), заканчивающееся двоеточием, работает с правым операндом.

Я понимаю, что:: (оператор "cons") заключается в том, что он используется таким образом, потому что добавление элемента в список (технически, создание нового списка с новым элементом, добавленным к старому списку) имеет значение O(1) в то время как добавление было бы O(N). Это вещь эффективности...

Чтобы добавить дополнительную информацию к другим ответам:

:: это подкласс List

final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { ... }

и метод на List

def ::[B >: A] (x: B): List[B] = new scala.collection.immutable.::(x, this)

который в основном реализован в терминах первого.

Так что за этим нет глубоких теоретических основ, просто имейте в виду правило о методах, заканчивающихся на :,

Другие вопросы по тегам