如何在名称冲突中配置扩展方法的优先级?

How can I configure the precedance of extension methods in name conflicts?

我想创建一个名为 "map" 的扩展方法来对单个对象进行内联映射。例如,如果您有一些 json 数据结构:

val json = getDataStructure()
val String text = json.customers.findFirst[address.city=="Hamburg"]
                      .map['''I want to use «it.firstname» often without tmp-vars.''']
                      .split(" ").join("\n")

不幸的是,我必须决定是要使用这个(我的)地图扩展方法还是要使用 ListExtensions.map 方法。

有没有办法避免这个问题?我也对隐藏扩展方法/使用优先级问题的一般答案感兴趣。

不幸的是,似乎没有任何文档说明通常如何处理优先级或如何隐藏隐式导入的 xtend 扩展。

如果库方法和您的自定义方法具有明确的签名,那么如果您使用静态扩展导入,它应该可以正常工作。我已经成功测试了这个:

package test1

class CustomListExtensions {

    static def <T, R> map(T original, (T)=>R transformation) {
        return transformation.apply(original);
    }
}

用法示例:

package test2

import static extension test1.CustomListExtensions.*

class Test1 {

    def static void main(String[] args) {

        // uses org.eclipse.xtext.xbase.lib.ListExtensions.map
        val mappedList = #["hello", "world"].map['''«it» has length «length»''']

        // uses test1.CustomListExtensions.map
        val mappedObject = "hello CustomListExtensions".map['''«it» has length «length»''']

        mappedList.forEach[println(it)]
        println(mappedObject)
    }

}

输出:

hello has length 5
world has length 5
hello CustomListExtensions has length 26

如果您使用扩展提供程序(使用非静态方法)而不是静态扩展导入,那么扩展提供程序似乎优先于库方法:

包测试1

class CustomListExtensions2 {

    def <T, R> map(T original, (T)=>R transformation) {
        return transformation.apply(original);
    }
}

用法:

package test2

import test1.CustomListExtensions2

class Test2 {

    val extension CustomListExtensions2 = new CustomListExtensions2

    def void main() {

        // uses test1.CustomListExtensions.map (<List<String>, String>)
        val mappedObject1 = #["hello", "world"].map['''«it» has length «length»''']

        // uses test1.CustomListExtensions.map (<String, String>)
        val mappedObject2 = "hello CustomListExtensions".map['''«it» has length «length»''']

        println(mappedObject1)
        println(mappedObject2)
    }

}

输出:

[hello, world] has length 2
hello CustomListExtensions has length 26