2014-01-11 1 views
0

[См. Фрагмент ниже] Я читал, что у меня есть X, который является Piece, и у меня есть Player, для которого требуется Piece. Игрок Me пытается определить эту пьесу с пьесой X. Тем не менее Scala не признает X как часть, а скорее видит «X.type». Что означает X.type? Я не совсем уверен, что моя проблема, поэтому мне трудно найти время.Scala не разрешает X как Y, хотя X расширяет Y

Я не вижу, как это может быть тип затенения [см. Scala really weird Type Mismatch], так как я не указываю другую «Пьесу», вместо этого я указываю только, что мне требуется «Пьеса».

Кажется, что есть что-то, что препятствует Скале разрешать Х как Кусок.

Чтобы попробовать в РЕПЛ

trait Piece { val piece: Char } 
case class X extends Piece { val piece: Char = 'X' } 

trait Player { val piece: Piece } 
case class Me extends Player { val piece: Piece = X } 

Результат

error: type mismatch; 
found : X.type 
required: Piece 
     case class Max extends Player { val piece: Piece = X } 

ответ

3

Это, вероятно, потому что X вы только описывающего класс (так что это на самом деле типа), в то время как Scala ожидает a объект (или экземпляр) типа Piece. Вы бы получить ту же ошибку, делая это в первом случае:

case class X extends Piece { val piece: Char = Char } 

Как вы можете видеть, ваша версия работает, потому что вы передаете специфический характер, а не тип. Если вы хотите, чтобы ваш код работать, вы, возможно, придется создать новый объект и передать его в:

case class Me extends Player { val piece: Piece = new X } 

EDIT: Как было отмечено ОП в комментарии ниже, с помощью X() также работает, потому что, как Х случай класса становится метод неявного применить():

case class Me extends Player { val piece: Piece = X() } 
+0

Ах, большое спасибо! У меня обычно есть параметр, поэтому я никогда не сталкивался с этой проблемой. Проблема с X() решает проблему. Не понимал класс IS типа. Теперь совпадение шаблонов шаблонов становится еще более ощутимым, и тот факт, что классы являются чертежами экземпляра, еще более ясен, потрясающий. Он просто щелкнул! – Miles

+0

Этот ответ на самом деле не совсем корректен. Не могли бы вы обновить его для согласования с моим ответом? Как раз в интересах, вы знаете, полезность. –

0

Вы присваивая тип X переменной piece, а не экземпляр X.

1

Когда вы пишете case class X, вы также создание спутника object X, который имеет элемент apply, что позволяет говорить X(). Все это очевидно после некоторого опыта работы с Scala.

X.type - одноэлементный тип объекта X. Он не имеет ничего общего с «назначением типа», как указывают другие ответы.

Когда вы говорите X в качестве значения, это означает, что объект. Это термин (то есть значение), а не тип.

Чтобы создать новый X, каждый пишет X(), что равно X.apply(), и никогда new X(). Никогда? Да, почти никогда.

Обратите внимание, что безразмерные классы классов давно устарели.

+0

Спасибо! Да, я не думаю, что вы можете «назначить тип», если вы не делаете что-то вроде 'type Cool = List [Int]', где вы создаете новый тип «Cool», который является List [Int] правильным? – Miles

+1

Технически вы не создаете новый тип в этом случае - 'Cool' - это псевдоним типа, означающий, что он точно такой же, как' List [Int] '. Создание нового типа означало бы 'class Cool extends List [Int]'. – sourcedelica

2

Примеры классов без параметров устарели. Вместо этого используйте case class X() и case class Me(). Таким образом вам нужно будет создать объект класса X с вызовом X(), как описано в других ответах.

В качестве альтернативы вы можете использовать case object S:

case object X extends Piece { val piece: Char = 'X' }. 

В самом деле, если вы используете случай объект здесь, ваш код начнет работать:

case class Me extends Player { val piece: Piece = X } // Works fine 

Это зависит от ваших требований, хотя. Возможно, вам нужны несколько экземпляров X; то объект объекта не для вас.

+0

Спасибо за это! Очищает, почему REPL жаловался на усталость. Используете ли вы объекты case над классами case, когда вам нужен только один экземпляр этого объекта? Я замечаю, что если вы используете объекты case, вы не можете сопоставлять шаблон как 'case (x: X) => println (" I am X ")', так как 'X' больше не является типом, а ссылкой на 'X 'вместо этого. Где я предполагаю, в этом случае вы должны были бы проверить что-то вроде 'if (x == X) println (« X спасибо »)' – Miles

+0

Вы можете сопоставить, используйте 'case X => println (" I am X ")' – sourcedelica

+0

@Miles, нет, 'if' не требуется. Вы можете напрямую сопоставлять, например 'case X => ...'. Я пишу это, потому что, скорее всего, у вас нет уведомления о комментарии sourcedelica. –

 Смежные вопросы

  • Нет связанных вопросов^_^