Как Вы определяете локальный var/val в основном конструкторе в Scala?

Что Вы будете видеть, иногда следующее:

class Abstract1( object ):
    """Some description that tells you it's abstract,
    often listing the methods you're expected to supply."""
    def aMethod( self ):
        raise NotImplementedError( "Should have implemented this" )

, поскольку Python не имеет (и не нуждается) формальный Интерфейсный контракт, различие стиля Java между абстракцией и интерфейсом не существуют. Если кто-то пройдет усилие определить формальный интерфейс, это также будет абстрактный класс. Единственные различия были бы в установленном намерении в docstring.

И различие между кратким обзором и интерфейсом незначительная вещь, когда у Вас есть утиный ввод.

Java использует интерфейсы, потому что он не имеет множественного наследования.

, поскольку Python имеет множественное наследование, можно также видеть что-то вроде этого

class SomeAbstraction( object ):
    pass # lots of stuff - but missing something

class Mixin1( object ):
    def something( self ):
        pass # one implementation

class Mixin2( object ):
    def something( self ):
        pass # another

class Concrete1( SomeAbstraction, Mixin1 ):
    pass

class Concrete2( SomeAbstraction, Mixin2 ):
    pass

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

60
задан giampaolo 17 August 2014 в 06:06
поделиться

4 ответа

Например,

class R(n: Int, d: Int) {
  val (x, y) = {
    val g = myfunc
    (n/g, d/g)
  }
}
37
ответ дан 24 November 2019 в 17:53
поделиться

Есть несколько способов сделать это. Вы можете объявить такие временные переменные внутри частных определений, которые будут использоваться во время строительства. Вы можете использовать временные переменные внутри блоков, которые возвращают выражения (например, в ответе Алаза). Или, наконец, вы можете использовать такие переменные внутри альтернативных конструкторов.

Аналогично альтернативным конструкторам, вы также можете определить их внутри метода «apply» объекта-компаньона.

Что вы можете ' t do объявляет поле «временным».

Обратите внимание, что любой параметр, полученный первичным конструктором, также является полем. Если вы не хотите, чтобы такие параметры становились полями и не хотите отображать фактические поля в конструкторе, обычное решение - сделать основной конструктор закрытым,

16
ответ дан 24 November 2019 в 17:53
поделиться

Некоторое обсуждение этой темы, включая комментарии Мартина Одерски, находится здесь

6
ответ дан 24 November 2019 в 17:53
поделиться

Другой вариант, который у нас есть, это сделать основной конструктор объектов Constructor и использовать метод применения объекта компаньона в качестве строителя. Если мы применим (PAL не предназначен) Этот подход к вашему примеру это будет выглядеть так:

class R private (val x: Int, val y: Int);

object R {
  def apply(n: Int, d: Int): R = {
    val g = myfunc;
    new R(n / g, d / g);
  }
}

для создания экземпляра R вместо:

val r = new R(1, 2);

Написать:

val r = R(1, 2);

Это немного многословна, но это может быть Хуже, я думаю :). Будем надеяться, что частные [этот] Vals будут рассматриваться как временные переменные в будущих выбросах SCALA. Мартин сам намекнул это.

13
ответ дан 24 November 2019 в 17:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: