In Haxe, can you write a generic interface where a method type parameter is constrained by the class's type parameter?

♀尐吖头ヾ 提交于 2020-05-30 03:54:29

问题


I'm having trouble writing the generic interface below.

In my class, I have a function that takes an array of < any type that extends a parent class > and traces its first element. Since I'm only reading elements from the array, I'm using it as if its a covariant compound type, and therefore I'm guaranteed to have the cast statement never fail.

Now I want to abstract this out even more and write a interface that defines fn using another generic type T. I want fn to be able to accept any Array < type that extends T >. When I have my test class implement this interface, I get the compiler error: "Field fn has different type than in ConstraintInter". How can I correct this interface? Or is there some other method/work around to accomplish this?

class TestParent { public function new() {} }
class TestChild extends TestParent { public function new() { super(); } }

@:generic
interface ConstraintInter<T>
{
    // this causes a compiler error
    public function fn<V:T>(arg:Array<V>):Void;
}

@:generic
class ConstraintTest<T> implements ConstraintInter<T>
{
    public function new () {}

    public function fn<V:T>(arg:Array<V>):Void
    {
        var first:T = cast arg[0];
        trace(first);
    }

    public function caller()
    {
        var test = new ConstraintTest<TestParent>();
        // var test = new ConstraintTest();
        // Base case that always works
        test.fn([new TestParent()]);

        // I want this to work.
        var childArray:Array<TestChild> = [new TestChild()];
        test.fn(childArray);

        // This should throw a compile error.
        // test.fn([3]);
    }
}

回答1:


You can using generic interface for that:

class TestParent { public function new() {} }
class TestChild extends TestParent { public function new() { super(); } }

@:generic
interface ConstraintInter<T>
{
    // this causes a compiler error when implemented in class below
    public function fn<V:T>(arg:Array<V>):Void;
}


class ConstraintTest implements ConstraintInter<TestParent>
{
    public function new () {}

    public function fn<V:TestParent>(arg:Array<V>):Void
    {
        var first:TestParent = cast arg[0];
        trace(first);
    }

    public function caller()
    {
        // Base case that always works
        fn([new TestParent()]);

        // I want this to work.
        var childArray:Array<TestChild> = [new TestChild()];
        fn(childArray);

        // This should throw a compile error.
        // fn([3]);
    }
}

Haxe 4.1.0



来源:https://stackoverflow.com/questions/61841914/in-haxe-can-you-write-a-generic-interface-where-a-method-type-parameter-is-cons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!