统一宏中的通用类型

凯文·雷索

我想使用宏来检查函数是否返回特定的泛型类型,例如Array,如果函数正在返回Array<Dynamic>Array<String>甚至泛型也很好Array<T>

所以我尝试Context.unifyArray<Dynamic>对于type参数为“ generic”的情况,它是否可行Array<String>还是Array<Dynamic>失败,因为ComplexTypeArray<T>不会使用转换为Type Type not found: T(请参见下面的代码)。有什么方法可以实现我的目标?

package;

#if macro
import haxe.macro.Context;
using haxe.macro.ComplexTypeTools;
#end

#if !macro @:build(Macros.build()) #end
class Main 
{
    public function test<T>():Array<T>
    {
        return [];
    }
}

class Macros
{
    public static function build()
    {
        #if macro
        var fields = Context.getBuildFields();
        for(field in fields)
        {
            switch(field.kind)
            {
                case FFun(f):
                    // try to unify Array<String> with Array<Dynamic>
                    trace(Context.unify((macro:Array<String>).toType(), (macro:Array<Dynamic>).toType())); 
                    // true

                    // try to unify Array<T> with Array<Dynamic>
                    trace(Context.unify(f.ret.toType(), (macro:Array<Dynamic>).toType())); 
                    // Type not found: T
                default:
            }
        }
        return null;
        #end
    }
}
米哈伊尔·伊格纳季耶夫(Mikhail Ignatiev)

更新

因此,检查TPath并不是最好的主意。基于先前关于Dynamic可分配给任何类型的假设,我们可以使用Dynamic(例如Array<T>= Array<Dynamic>替换不可转换的类型参数,并在尝试统一它时进行替换

static function toTypeExt(c:ComplexType):Null<haxe.macro.Type>
{
    try {
        return c.toType();          
    } catch (error:Error)
    {                   
        switch (c)                          
        {
            case TPath(p):                  
                //deep copy of the TPath with all type parameters as Dynamic
                var paramsCopy = [for (i in 0...p.params.length) TPType(macro:Dynamic)];
                var pCopy:TypePath = {
                    name: p.name,
                    pack: p.pack,
                    sub: p.sub,
                    params: paramsCopy
                }
                var cCopy = TPath(pCopy);

                //convert after
                return cCopy.toType();
            default:                    
        }
    }

    return null;
}

在构建宏中使用toTypeExt()而不是toType。

trace(Context.unify(toTypeExt(f.ret), (macro:Array<Dynamic>).toType()));

在我看来,这更像是一种解决方法,但是ComplexTypeTools.toType有一个奇怪的事情-它会在使用类类型参数的情况下成功,而在方法类型参数的情况下失败。

老答案

统一将无法正常工作,因为无法将带有type参数的ComplexType转换为Type(在这种情况下)。但是,由于您要与Array统一,因此可以安全地假定任何Array都可以与其统一(因为任何类型都可以分配给Dynamic http://haxe.org/manual/types-dynamic.html)。


可能不是最简单的解决方案,但是简单的TPath检查是解决问题的方法:

    case FFun(f):                   
        switch (f.ret) {
                case TPath({ name: "Array", pack: [], params: _ }):
                    trace("Yay!");
                default:                            
        }

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

匹配Scala宏中的通用类型

来自分类Dev

类型中要统一的类型变量

来自分类Dev

类型中要统一的类型变量

来自分类Dev

类型错误将结构传递给通用Lisp中的宏

来自分类Dev

如何在Scala的宏注释中访问通用类型?

来自分类Dev

防止类型统一

来自分类Dev

防止类型统一

来自分类Dev

通用参数扩展类型,但位置相反,且打字稿无法统一它

来自分类Dev

如何统一更改GUI中的字体类型

来自分类Dev

如何统一更改GUI中的字体类型

来自分类Dev

为什么类型/类统一主要在python中

来自分类Dev

如何统一这些类型?

来自分类Dev

统一记录类型

来自分类Dev

多参数类型类的类型统一

来自分类Dev

通用约束中的通用类型

来自分类Dev

通用约束中的通用类型

来自分类Dev

Typescript 中的通用类型

来自分类Dev

仅在一类中设置通用类型

来自分类Dev

仅在一类中设置通用类型

来自分类Dev

使用宏在C中实现通用向量。这是一个好主意吗?

来自分类Dev

开放对象类型过早统一

来自分类Dev

递归数据类型的统一

来自分类Dev

Isabelle类型统一/推断错误

来自分类Dev

注册类型时出现统一异常

来自分类Dev

开放对象类型过早统一

来自分类Dev

循环宏中的通用Lisp绑定

来自分类Dev

在OpenGL中设置统一

来自分类Dev

OpenTK中的布尔统一

来自分类Dev

将回购的多个版本统一管理到通用基础分支中-最佳实践工作流?