Поиск документации Scala для #::
Я пытаюсь найти документацию для метода оператора Scala #::
. Я считаю, что он определен в классе Stream
из-за пример, который я нашел, который использует его.
Мой вопрос не относится к этому методу (хотя я хотел бы знать, где находятся документы), но как искать документы Scala в целом. Я попытался ввести #::
в поле поиска в левом верхнем углу страницы документации (2.8.1), но ничего не нашел.
Ответы
Ответ 1
Я предлагаю использовать Справочный указатель - он разработан специально для поиска любого символа (класс, черты, методы, vals, vars ) независимо от его иерархической позиции - в отличие от индекса левой руки Scaladoc, который не показывает внутренние классы, черты или объекты.
К сожалению, он доступен только в ночное время. Вы можете увидеть все это в ночной Scaladoc. Обратите внимание на верхний квадрат в левом фрейме над индексом.
Надеюсь, что он будет связан с Scala 2.9.0.
Изменить. Начиная с 2.9.0, ссылочный индекс начал связываться с Scaladoc. Не нужно теперь обращаться к ночным документам.
Ответ 2
Как уже упоминалось, #::
определяется на scala.collection.immutable.Stream.ConsWrapper
. Я просто хотел немного подумать, почему это так.
В общем случае для вызова оператора на объект этот объект должен существовать. Однако идея с потоком - это хвост потока, который не оценивается до тех пор, пока это не будет. Итак, рассмотрим следующий поток:
def fibs(a:Int,b:Int):Stream[Int] = a #:: fibs(b,a+b)
Обычно нам нужно оценить рекурсивный вызов fibs
, чтобы мы могли называть его #::
. Это приведет к безудержной рекурсии. Это НЕ то, что мы хотим. Мы хотим, чтобы получатель был по-имени Stream
. Следовательно, ConsWrapper
:
Конструктор для ConsWrapper
- это class ConsWrapper[T](tail: => Stream[T])
, берущий по имени Stream
, и он создается через неявное преобразование Stream.consWrapper[T](stream: => Stream[T])
, которое также принимает по имени Stream
.
Следовательно, мы выполнили неявное преобразование результата функции, которая еще не была вызвана, и мы наметили эффект вызова #::
с помощью ссылки this
по имени.
Ответ 3
Проблема заключается в том, что скалярный поиск не позволяет вам искать внутренний класс/объект (т.е. чей родитель не является пакетом). Объявление #::
равно либо Stream.#::
, либо Stream.ConsWrapper.#::
:
object Stream {
//STUFF
/** An extractor that allows to pattern match streams with `#::`.
*/
object #:: {
def unapply[A](xs: Stream[A]): Option[(A, Stream[A])] =
if (xs.isEmpty) None
else Some((xs.head, xs.tail))
}
class ConsWrapper[A](tl: => Stream[A]) {
def #::(hd: A): Stream[A] = new Stream.Cons(hd, tl)
def #:::(prefix: Stream[A]): Stream[A] = prefix append tl
}
//MORE STUFF
}
Вы можете запросить это как RFE для инструмента scaladoc в trac.
В плагине IntelliJ IDEA scala вы могли бы использовать поиск символов (CTRL + ALT + SHIFT + N) и набрали #::
, и это было бы немедленно отобразили обе декларации #::
.
Ответ 4
Хорошо, обычно, если мы видим
foo bar baz
тогда bar - это метод, определенный для foo, поэтому мы сначала рассмотрим определение класса/объекта foo, затем дерево наследования/дерева признаков вверх (+ в неявных преобразованиях и из foo в текущем файле и в (напрямую) включены файлы).
За исключением "bar" заканчивается двоеточие, что здесь и происходит. Затем его следует читать в обратном порядке -
foo bar: baz
не
foo.bar: (baz)
но
baz.bar: (foo)
Итак, мы должны искать способ, описанный выше, но не для foo, а для baz.
Ответ 5
Этот конкретный метод определен в вложенном классе внутри Stream
, называемом scala.collection.immutable.Stream.ConsWrapper
.
И нет, я понятия не имею, как можно найти его. Я случайно наткнулся на него. И хотя я знал, где его найти сейчас, когда я хотел опубликовать ссылку на класс здесь, в моем ответе, я все еще не мог найти его в первой (и даже второй и третьей) попытке.