问题
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