如何在名称冲突中配置扩展方法的优先级?
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
我想创建一个名为 "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