Присвоение значения по умолчанию параметру T: Float type

У меня есть класс, который я хотел динамически определять, какой тип принимать, но все же иметь тип float. Я добавил пример класса ниже. Проще говоря, мне нужен класс, который может содержать либо Ints, либо Float (или абстракции (Float)), но параметру типа не нравится, когда ему назначают что-то, что действительно должно ему соответствовать.

class Container<T:Float>
{
    public function new(aValue:T = 0.0) 
    {
    }

    public function example():T 
    {
        return 16.0;
    }

В этом примере я получаю две ошибки компилятора. Первый - это значение по умолчанию конструктора new(aValue:T = 0.0. Простое исправление - установить значение как динамическое, но мне нравится мой код более аккуратным, чем этот. Вторая ошибка - в возвращаемом значении example (). Это не позволит мне вернуть 16.0, так как это не экземпляр T.

Мой вопрос: возможно ли это, и если нет, следует ли мне использовать разные определения классов для каждого типа?


person oli_chose123    schedule 12.09.2017    source источник


Ответы (2)


Я думаю, проблема здесь в том, что вам действительно не нужен общий тип "T".

Вот что я придумал, учитывая ваши ограничения. Класс «Контейнер» не является универсальным и содержит просто конструктор типа Float. Однако это по-прежнему позволяет ему принимать любое значение, которое может быть неявно преобразовано в Float, включая любые abstract, если они определяют правила преобразования.

package ;

class Main
{
    public static function main()
    {
        new Container(); // default
        new Container(1); // Int
        new Container(2.3); // Float
        new Container(new UnifiesWithFloat(4.5)); // Float abstract
    }
}

class Container
{
    public function new(aValue:Float = 0.8) 
    {
        trace('aValue is $aValue');
    }
}

abstract UnifiesWithFloat(Float) from Float to Float
{
    inline public function new(value:Float)
    {
        this = value;
    }
}
person bsinky    schedule 12.09.2017
comment
Хотя это простое решение работает достаточно хорошо для некоторых ситуаций, оно не будет работать для рефератов, не содержащих from Float to Float. Если бы вы могли присваивать значения параметру типа, который является Float, вы могли бы поддерживать любой вид абстрактного, который поддерживает перегрузки операций с плавающей запятой. Конечно, если нет возможности присвоить значения параметру типа с плавающей запятой, то простой контейнер с плавающей запятой является лучшим и наиболее эффективным решением. - person oli_chose123; 13.09.2017
comment
Погодите, душ помог. Мой предыдущий комментарий не работает как абстракция, которая, строго говоря, не является типом с плавающей запятой. Что мне действительно нужно, так это способ указать возможные перегрузки операторов в типе, и я не думаю, что это возможно. Затем я выберу ваш ответ как правильный. - person oli_chose123; 13.09.2017

Единственный способ решить эту проблему - использовать cast и самостоятельно разрешить необязательные параметры.

class Test {
    static function main() {
        $type(new Container(1));
        $type(new Container(1).example());
        new Container(1).example();

        $type(new Container(1.0));
        $type(new Container(1.0).example());
        new Container(1.0).example();
    }
}

class Container<T:Float> {
    public var value:T;

    public function new(aValue:T) {
        this.value = cast (aValue != null ? aValue : 0);
    }

    public function example():T {
        return cast 16;
    }
}

Журналы:
Test.hx:3: characters 14-30 : Warning : Container<Int> Test.hx:4: characters 14-40 : Warning : Int Test.hx:7: characters 14-32 : Warning : Container<Float> Test.hx:8: characters 14-42 : Warning : Float

person Mark Knol    schedule 27.09.2017