2016-01-06 2 views
0

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

Учитывая перечень и функции, соответственно:

var l = List[Int]() 

def append[U](cmd: U) = { 
     l = l :+ cmd 
} 

При интерпретации кода выше, я получаю следующее сообщение об ошибке:

<console>:10: error: type mismatch; 
found : List[Any] 
required: List[Int] 
        l = l :+ cmd 
         ^

Как я установил его, был модификацией функция append работает следующим образом:

def append[U](cmd: U) = { 
    l = (l :+ cmd).asInstanceOf[List[Int]] 
    } 

Есть ли способ определить приложение end без использования asInstanceOf?

Стараясь быть яснее, цель состояла в том, чтобы создать класс ниже

abstract class Cstruct{ 
    type T 
    var value: T 
    def append[U](value:U) 
} 

Cstruct должен быть построен таким образом, чтобы можно было бы определить новые классы, которые распространяются Cstruct, но используют разные структуры данных для значения T. Подобно Cseq, который использует список любых типов элементов, но должен быть возможен для создания аналогичного с помощью Set или Map.

class Cseq[U] (v: U) extends Cstruct{ 
    type T = List[U] 
    var value: T = List[U](v) 
    override def append[U](cmd: U) = { 
    value = (value :+ cmd).asInstanceOf[T] 
    } 
} 
+0

Почему 'append' generic? Вы можете только добавить 'Int' (или супертип) в 'List [Int]' – Lee

ответ

2

Вы получаете эту ошибку, потому что ваш тип переменной U не имеет ограничений, это может быть любой тип - пока вы пытаетесь добавить значение типа U к списку Int.

Ваше исправление не является безопасным. Это позволит вам попытаться добавить, например, String в List[Int]. asInstanceOf делает ошибку компиляции, но вы получите ClassCastException во время выполнения, если вы добавите неправильный тип объекта в список.

Почему у вашего метода есть параметр типа вообще? Если список всегда List[Int], то он должен просто взять Int вместо U:

def append(cmd: Int) = { 
    l = l :+ cmd 
} 

редактировать - Вы можете сделать это:

abstract class Cstruct[U] { 
    type T 
    var value: T 
    def append(value: U) 
} 

class Cseq[U](v: U) extends Cstruct[U] { 
    type T = List[U] 
    var value: T = List[U](v) 

    override def append(cmd: U) = 
    value = value :+ cmd 
} 

Обратите внимание, что в вашем собственном определении Cseq[U], U в override def append[U] является другим типом параметра, чем тот, который определен в class Cseq[U]. Просто одно и то же имя U.

+0

Это не всегда будет List [Int], в качестве примера использовался List [Int], метод append имеет параметр типа потому что он должен быть общим. – TFR

+0

@TFR См. Мое редактирование. Это полезное решение для вас? – Jesper

+0

Спасибо, это именно то, что я искал. – TFR

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