Kotlin, проблема с созданием экземпляра и общий

#kotlin

#kotlin

Вопрос:

У меня есть класс Vec3i, который расширяет Vec3t

 data class Vec3i(
  override var x: Int = 0,
  override var y: Int = 0,
  override var z: Int = 0
) : Vec3t(x, y, z)
  

это имеет в качестве одного вторичного конструктора следующее

 constructor(v: Vec3t<Number>) : this(v.x.toInt(), v.y.toInt(), v.z.toInt())
  

и еще один класс Vec3ub, который всегда расширяет Vec3t

 data class Vec3ub(
  override var x: Ubyte = Ubyte(0),
  override var y: Ubyte = Ubyte(0), 
  override var z: Ubyte = Ubyte(0)
) : Vec3t(x, y, z)
  

Где Vec3t, в свою очередь

 abstract class Vec3t<T : Number>(
  override var x: T, 
  override var y: T, 
  open var z: T
) : Vec2t(x, y)
  

И Ubyte расширяет число

Я хотел бы создать экземпляр Vec3i из Vec3ub

 Vec3i(vec3ub)
  

но компиляторы жалуются, что для этого нет конструктора..

почему недопустим вторичный конструктор, который я цитировал ранее?

Комментарии:

1. Вы должны включить параметры типа, чтобы сделать этот вопрос допустимым. Например, Vec3t отсутствует параметр T type. Кроме того, constructor(v : Vec3t) необходимо иметь этот параметр. Если я исправлю код с необходимыми параметрами типа, код компилируется правильно.

2. Извините, они потерялись, когда я написал их на макушке, у меня они есть в коде, но я все равно получаю ошибку

Ответ №1:

Для полноты картины, как указано в моем комментарии, следующее компилируется правильно:

 data class Vec3i(
        override var x: Int = 0,
        override var y: Int = 0,
        override var z: Int = 0
) : Vec3t<Int>(x, y, z) {

    constructor(v: Vec3t<out Number>) : this(v.x.toInt(), v.y.toInt(), v.z.toInt())
}

data class Vec3ub(
        override var x: Ubyte,
        override var y: Ubyte,
        override var z: Ubyte
) : Vec3t<Ubyte>(x, y, z)

abstract class Vec3t<T>(
        override var x: T,
        override var y: T,
        open var z: T
) : Vec2t<T>(x, y)

open class Vec2t<T>(
        open var x: T,
        open var y: T
)

fun test(vec3ub: Vec3ub) {
    val vec3i = Vec3i(vec3ub)
}

abstract class Ubyte : Number() 
  

Обратите внимание на constructor(v : Vec3t<out Number>) : ... и все другие добавленные общие типы параметров. Vec3t<out Number> необходимо, а не только Vec3t<Number> здесь, поскольку вы передаете не a Number , а скорее его подкласс.

Комментарии:

1. Виновником было out ключевое слово.. Я не очень хорошо понял разницу между in и out из документа, можете ли вы быстро разъяснить это в общих чертах?

2. Это сложно, «быстро» не применяется. kotlinlang.org/docs/reference/generics.html … лучше всего задать это на форумах, в slack и т. Д., Потому что это обсуждение, а не вопрос в стиле SO.