Generics 如何在Haxe(haxe3)中编写通用比较函数
我试图在Haxe3中为模板类型a编写一个通用比较函数(如c strcmp),假设此模板类型具有小于或等于运算符“两种类型安全的方法来处理此问题: 1.宏Generics 如何在Haxe(haxe3)中编写通用比较函数,generics,haxe,generic-programming,Generics,Haxe,Generic Programming,我试图在Haxe3中为模板类型a编写一个通用比较函数(如c strcmp),假设此模板类型具有小于或等于运算符“两种类型安全的方法来处理此问题: 1.宏 主类{ 宏静态公共函数比较(a,b) 返回宏@:pos(a.pos){ 变量a=$a, b=b美元; 如果(a)不确定我是否完全理解了你的问题。是Reflect.compare(a,b)与你想要的接近吗?这是一个@:coreApi,这意味着它是针对每个平台分别实现的。请参见此处的Javascript实现:……不确定如何使用该或模板的“le()进
主类{
宏静态公共函数比较(a,b)
返回宏@:pos(a.pos){
变量a=$a,
b=b美元;
如果(a)不确定我是否完全理解了你的问题。是Reflect.compare(a,b)与你想要的接近吗?这是一个@:coreApi
,这意味着它是针对每个平台分别实现的。请参见此处的Javascript实现:……不确定如何使用该或模板的“le()进行比较“不过函数…谢谢,Jason。我试过Reflect.compare(a,b)。但我希望a,b都来自模板类型T。我记得haxe编译告诉我,只有该类型在运行时才知道,而不是在编译时。类似于function compare_ux(x:a,y:a):Int{return Reflect.compare(a,b);}
。我想我想要一些可以隐式使用"我正在寻找不涉及宏的轻量级解决方案,因为我打算在其他语言中重复使用haxe生成的代码,而不依赖于引导或scuts。动态对我来说也不好,因为根本没有类型安全性。
没有这样的解决方案。你一直在谈论模板,而实际上只有类型米。这是问题的一个重要部分。如果你想拥有模板的功能,你必须使用宏。或者你必须使用反射,但这也有局限性。你必须删除一些约束以允许解决方案空间;)这可能是一个语言问题。HAXE类型参数看起来与C++模板类型类似。所以,这就是模板类型的意思。我想做的是,可以使用生成的C++代码而不需要整个引导机制。到目前为止,C++将不会检查类型参数是否有“一个”。
@:generic static function foo<T:{function new(s:String):Void;}>(t:T) {
trace(Type.typeof(t)); // TClass([class String]) / TClass([class Template])
return new T("foo");
}
class Main {
@:generic static public function compare_<A:{function le(y:A):Bool;}>(x:A,y:A): Int {
if (x.le(y) && y.le(x)) return 0;
else if (x.le(y)) return -1;
else return 1;
}
static function main() {
var a:MyInt = new MyInt(1);
var b:MyInt = new MyInt(2);
trace(compare_(a,b));
}
}
class MyInt {
var data:Int;
public function new(i:Int) {this.data = i; }
public function le(y:MyInt){return data <= y.data;}
}
@:generic static public function compare_<A:{@:op(X <= Y) function le(x:A,y:A):Bool;}>(x:A,y:A): Int {
if (x <= y && y <= x) return 0;
else if (x <= y) return -1;
else return 1;
}
class Main {
macro static public function compare_(a, b)
return macro @:pos(a.pos) {
var a = $a,
b = $b;
if (a <= b)
if (b <= a) 0;
else -1;
else 1;
}
static function main() {
var a = 1,
b = 2;
trace(compare_(a,b));
}
}
abstract Comparator<T>({f: T->Int }) {
public function new(f)
this = { f: f };
public function compare(other:T):Int
return this.f(other);
@:from static function fromInt(i:Int)
return simple(i);
@:from static function fromFloat(f:Float)
return simple(f);
@:from static function fromString(s:String)
return simple(s);
@:from static function fromComparable<A>(o:{ function compareTo(other:A):Int; })
return new Comparator(o.compareTo);
static function simple<X>(o:X):Comparator<X>
return new Comparator(Reflect.compare.bind(o));
}
class Main {
static public function compare_<A>(a:Comparable<A>, b:A)
return a.compare(b);
static function main() {
function comparable(value)
return {
value: value,
compareTo: function(other)
return Reflect.compare(value, other.value)
}
trace(compare_(1,2));
trace(compare_(1.5,2.5));
trace(compare_('foo','bar'));
trace(compare_(comparable(1),comparable(2)));
}
}