Scala Arrays vs Векторы - PullRequest
9 голосов
/ 26 мая 2011

Scala newb ... Я запутался

object myApp extends App {
  println("Echo" + (args mkString " "))
}

"args" - это тип Array [String], но в скалярном массиве Array такого метода нет.mkString - это метод для Vector, но я не вижу никакой наследственной связи между ними.Так почему же мы можем использовать метод mkString для аргументов?

Ответы [ 3 ]

17 голосов
/ 26 мая 2011

Я не эксперт по скалам (далеко не так!), Но я думаю, что ответ - неявные преобразования (см. scala.Predef) и WrappedArray.scala.

В частности, Predef имеет следующее неявное преобразование:

implicit def genericWrapArray [T] (xs: Array[T]): WrappedArray[T] 

И у WrappedArray есть метод mkString. Когда scala не может найти метод mkString в Array, он ищет неявное преобразование в тип, который делает.

http://www.scala -lang.org / апи / ток / Скала / Predef $. HTML

http://www.scala -lang.org / апи / ток / Скала / Коллекция / изменяемые / WrappedArray.html

12 голосов
/ 26 мая 2011

Расширяя ответ Кевина и объясняя, почему scaladoc не может сказать вам, что существует неявное преобразование: неявные преобразования вступают в действие только тогда, когда ваш код не компилируется иначе.

Выможет видеть это как механизм восстановления ошибок типа, который активируется во время компиляции.В этом случае Array[String] не имеет метода mkString.Этот код не будет компилироваться, потому что этот метод не существует в Array[T].Но перед отказом компилятор будет искать неявное преобразование в области.

Бывает, что Predef приносит несколько неявных преобразований в области и одно, которое будет применяться здесь.

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

$ scalac -d classes -Xprint:typer A.scala
[[syntax trees at end of typer]]// Scala source: A.scala
package <empty> {
  final object myApp extends java.lang.Object with App with ScalaObject {
    def this(): object myApp = {
      myApp.super.this();
      ()
    };
    scala.this.Predef.println("Echo ".+(scala.this.Predef.refArrayOps[String](myApp.this.args).mkString(" ")))
  }
}

Таким образом, вы можете видеть, что Predef.refArrayOps на самом деле является неявным использованным преобразованием.Он преобразует ваш массив в ArrayOps[String], который имеет mkString метод .

Так что, имея в виду, вы можете понять, почему scaladoc для Arrayне могу сказать вам, что неявное преобразование может применяться.Это может быть что угодно.На самом деле это полностью основано на том, что такого метода не существует.Только компилятор будет знать, что неявное было найдено на основе кода.

Вы даже можете определить свое собственное неявное преобразование:

object myApp extends App {
  implicit def myImplicit(arr:Array[String]) = new {
    def mkString(s:String) = arr.length + s
  }
  println("Echo " + (args mkString(" ")))
}

, которое будет иметь следующий эффект:

$ scala -cp classes myApp a b c
Echo 3

Очевидно, что скардок не сможет это показать.Обратите внимание, что плагин Eclipse Scala может привести к реализации mkString, нажав F3 (в итоге вы получите TraversableOnce).

2 голосов
/ 30 мая 2011

Но Scaladoc мог бы, по крайней мере, сказать, что Predef (который особенный, потому что он всегда находится в области видимости) имеет неявное преобразование из Array. Это было бы полезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...