Пример фабричного метода в искровой оболочке, дающей ошибку

Я не могу запустить код ниже в искровой оболочке repl. Это репродукция из примера кулинарной книги Scala, предоставленного Элвином Александром. получить ошибку:

<console>:22: error: reference to Animal is ambiguous;
it is imported twice in the same scope by
import $VAL11.Animal
and import INSTANCE.Animal
       val test = Animal("dog")

Это отлично работает с Scala repl. Не могли бы вы рассказать мне, как я могу заставить этот пример работать и на spark-shell?

Большое спасибо за твою помощь!

trait Animal {
    def speak
}
object Animal {
    private class Dog extends Animal {
        override def speak = {
            println("woof")
        }
    }

    private class Cat extends Animal {
        override def speak { println("meow") }
    }
    def apply(s: String):Animal = {
        if (s == "dog") return new Dog
        else return new Cat
    }

}


# repl
Animal("dog") 

# compiling
object test {
    def main(args: Array[String]){
        Animal(args(0)).speak
    }
}

person VeryLucky XYZ    schedule 26.04.2016    source источник
comment
Используйте команду :paste, чтобы Animal компаньоны были скомпилированы вместе. Это твой вопрос?   -  person som-snytt    schedule 26.04.2016
comment
Спасибо @som-snytt. Я использую :paste. После вашего комментария я понял, что запускаю их в искровой оболочке, а не в scala repl. Я изменю свой вопрос.   -  person VeryLucky XYZ    schedule 26.04.2016
comment
Вероятно, issues.scala-lang.org/browse/SI-9740. Если вы попробуете Animal("pug") // show, он может показать, что импортировано.   -  person som-snytt    schedule 26.04.2016


Ответы (1)


Как указал som-snytt, это, скорее всего, версия существующей ошибки scala.

Animal("dog") // show 

получается что-то вроде этого:

import $line15.$read.INSTANCE.$iw.$iw.Animal;
val $line15$read = $line15.$read.INSTANCE;
import $line15$read.$iw.$iw.Animal;

Обратите внимание, что Animal импортируется дважды. Чтобы исправить это, вы можете обернуть свой код в object:

object test{
  trait Animal {
    def speak
  } 

  object Animal {
    private class Dog extends Animal {
      override def speak = {
        println("woof")
      }
    }

    private class Cat extends Animal {
      override def speak { println("meow") }
    }

    def apply(s: String):Animal = {
      if (s == "dog") return new Dog
      else return new Cat
    }
  } 
}

Теперь, когда вы вызываете test.Animal("dog") // show, вместо этого вы получаете это:

val $line15$read = $line15.$read.INSTANCE;
import $line15$read.$iw.$iw.$iw.$iw.$iw.$iw.$iw.$iw.test;

Обратите внимание, что вы получаете только один, более краткий импорт.

Интересно отметить, что если вы запустите свой первый код, а затем второй, то test.Animal("dog") приведет к следующему результату:

import $line15.$read.INSTANCE.$iw.$iw.Animal;
val $line16$read = $line16.$read.INSTANCE;
import $line16$read.$iw.$iw.$iw.$iw.$iw.$iw.$iw.$iw.test;

Где остается импорт Animal.

person Justin Pihony    schedule 26.04.2016