如何在groovy中实现java.util.Map的类上使用propertyMissing
我理解这一点,因为在groovy中能够获得带有点符号的映射键 现在,对于一个实现java.util.Map的类来说,有没有一种方法仍然可以从使用propertyMissing的expando元类中获益 以下是我正在尝试的:如何在groovy中实现java.util.Map的类上使用propertyMissing,groovy,Groovy,我理解这一点,因为在groovy中能够获得带有点符号的映射键 现在,对于一个实现java.util.Map的类来说,有没有一种方法仍然可以从使用propertyMissing的expando元类中获益 以下是我正在尝试的: LinkedHashMap.metaClass.methodMissing = { method, args -> println "Invoking ${method}" "Invoking ${method}" } LinkedHashMap.me
LinkedHashMap.metaClass.methodMissing = { method, args ->
println "Invoking ${method}"
"Invoking ${method}"
}
LinkedHashMap.metaClass.propertyMissing = { method, args ->
println "Accessing ${method}"
"Accessing ${method}"
}
def foo = [:]
assert "Invoking bar" == foo.bar() // this works fine
assert "Accessing bar" == foo.bar // this doesn't work, for obvious reasons, but I'd like to be able to do that...
我一直在尝试自定义delegatingmetaclass,但没有成功…不确定它是否适合您的用例,但您可以在地图上使用Guava和带默认值的
方法
@Grab( 'com.google.guava:guava:16.0.1' )
import static com.google.common.base.CaseFormat.*
def map
map = [:].withDefault { key ->
LOWER_UNDERSCORE.to(LOWER_CAMEL, key).with { alternate ->
map.containsKey(alternate) ? map[alternate] : null
}
}
map.possibleSolution = 'maybe'
assert map.possible_solution == 'maybe'
这样做的一个副作用是,在断言之后,映射包含两个键:值对:
assert map == [possibleSolution:'maybe', possible_solution:'maybe']
不确定它是否适合您的用例,但您可以在地图上使用Guava和with default
方法
@Grab( 'com.google.guava:guava:16.0.1' )
import static com.google.common.base.CaseFormat.*
def map
map = [:].withDefault { key ->
LOWER_UNDERSCORE.to(LOWER_CAMEL, key).with { alternate ->
map.containsKey(alternate) ? map[alternate] : null
}
}
map.possibleSolution = 'maybe'
assert map.possible_solution == 'maybe'
这样做的一个副作用是,在断言之后,映射包含两个键:值对:
assert map == [possibleSolution:'maybe', possible_solution:'maybe']
不确定它是否适合您的用例,但您可以在地图上使用Guava和with default
方法
@Grab( 'com.google.guava:guava:16.0.1' )
import static com.google.common.base.CaseFormat.*
def map
map = [:].withDefault { key ->
LOWER_UNDERSCORE.to(LOWER_CAMEL, key).with { alternate ->
map.containsKey(alternate) ? map[alternate] : null
}
}
map.possibleSolution = 'maybe'
assert map.possible_solution == 'maybe'
这样做的一个副作用是,在断言之后,映射包含两个键:值对:
assert map == [possibleSolution:'maybe', possible_solution:'maybe']
不确定它是否适合您的用例,但您可以在地图上使用Guava和with default
方法
@Grab( 'com.google.guava:guava:16.0.1' )
import static com.google.common.base.CaseFormat.*
def map
map = [:].withDefault { key ->
LOWER_UNDERSCORE.to(LOWER_CAMEL, key).with { alternate ->
map.containsKey(alternate) ? map[alternate] : null
}
}
map.possibleSolution = 'maybe'
assert map.possible_solution == 'maybe'
这样做的一个副作用是,在断言之后,映射包含两个键:值对:
assert map == [possibleSolution:'maybe', possible_solution:'maybe']
如果我理解清楚,您可以提供自定义地图:
class CustomMap extends LinkedHashMap {
def getAt(name) {
println "getAt($name)"
def r = super.getAt(name)
r ? r : this.propertyMissing(name)
}
def get(name) {
println "get($name)"
super.get(name)
def r = super.get(name)
r ? r : this.propertyMissing(name)
}
def methodMissing(method, args) {
println "methodMissing($method, $args)"
"Invoking ${method}"
}
def propertyMissing(method) {
println "propertyMissing($method)"
"Accessing ${method}"
}
}
def foo = [bar:1] as CustomMap
assert foo.bar == 1
assert foo['bar'] == 1
assert foo.lol == 'Accessing lol'
assert foo['lol'] == 'Accessing lol'
assert foo.bar() == 'Invoking bar'
如果我理解清楚,您可以提供自定义地图:
class CustomMap extends LinkedHashMap {
def getAt(name) {
println "getAt($name)"
def r = super.getAt(name)
r ? r : this.propertyMissing(name)
}
def get(name) {
println "get($name)"
super.get(name)
def r = super.get(name)
r ? r : this.propertyMissing(name)
}
def methodMissing(method, args) {
println "methodMissing($method, $args)"
"Invoking ${method}"
}
def propertyMissing(method) {
println "propertyMissing($method)"
"Accessing ${method}"
}
}
def foo = [bar:1] as CustomMap
assert foo.bar == 1
assert foo['bar'] == 1
assert foo.lol == 'Accessing lol'
assert foo['lol'] == 'Accessing lol'
assert foo.bar() == 'Invoking bar'
如果我理解清楚,您可以提供自定义地图:
class CustomMap extends LinkedHashMap {
def getAt(name) {
println "getAt($name)"
def r = super.getAt(name)
r ? r : this.propertyMissing(name)
}
def get(name) {
println "get($name)"
super.get(name)
def r = super.get(name)
r ? r : this.propertyMissing(name)
}
def methodMissing(method, args) {
println "methodMissing($method, $args)"
"Invoking ${method}"
}
def propertyMissing(method) {
println "propertyMissing($method)"
"Accessing ${method}"
}
}
def foo = [bar:1] as CustomMap
assert foo.bar == 1
assert foo['bar'] == 1
assert foo.lol == 'Accessing lol'
assert foo['lol'] == 'Accessing lol'
assert foo.bar() == 'Invoking bar'
如果我理解清楚,您可以提供自定义地图:
class CustomMap extends LinkedHashMap {
def getAt(name) {
println "getAt($name)"
def r = super.getAt(name)
r ? r : this.propertyMissing(name)
}
def get(name) {
println "get($name)"
super.get(name)
def r = super.get(name)
r ? r : this.propertyMissing(name)
}
def methodMissing(method, args) {
println "methodMissing($method, $args)"
"Invoking ${method}"
}
def propertyMissing(method) {
println "propertyMissing($method)"
"Accessing ${method}"
}
}
def foo = [bar:1] as CustomMap
assert foo.bar == 1
assert foo['bar'] == 1
assert foo.lol == 'Accessing lol'
assert foo['lol'] == 'Accessing lol'
assert foo.bar() == 'Invoking bar'
我重新阅读了,注意到get方法有两个版本。一个接受一个参数,另一个接受2
采用2的版本几乎与我在这里描述的一样:如果找不到您的密钥,它将返回一个默认值
我得到了想要的效果,但不是点符号,因此我只是将此作为一种替代方案发布,以防有人看到此帖子:
Map.metaClass.customGet = { key ->
def alternate = key.replaceAll(/_\w/){ it[1].toUpperCase() }
return delegate.get(key, delegate.get(alternate, 'Sorry...'))
}
def m = [myKey : 'Found your key']
assert 'Found your key' == m.customGet('myKey')
assert 'Found your key' == m.customGet('my_key')
assert 'Sorry...' == m.customGet('another_key')
println m
-结果-
m=[我的钥匙:找到你的钥匙,我的钥匙:找到你的钥匙,另一个钥匙:对不起…,另一个钥匙:对不起…]
在Tim的解决方案中,这导致m在第二个assert+2个键之后包含两个键,并带有默认值(对不起…),每次我们请求初始映射中不存在的新值时。。。这可以通过删除具有默认值的键来解决。e、 g:
Map.metaClass.customGet = { key ->
def alternate = key.replaceAll(/_\w/){ it[1].toUpperCase() }
def ret = delegate.get(key, delegate.get(alternate, 'Sorry...'))
if (ret == 'Sorry...') {
delegate.remove(key)
delegate.remove(alternate)
}
ret
}
请随意评论/更正可能导致的任何错误。。。在这里大声思考…我重新阅读了,我注意到get方法有两个版本。一个接受一个参数,另一个接受2
采用2的版本几乎与我在这里描述的一样:如果找不到您的密钥,它将返回一个默认值
我得到了想要的效果,但不是点符号,因此我只是将此作为一种替代方案发布,以防有人看到此帖子:
Map.metaClass.customGet = { key ->
def alternate = key.replaceAll(/_\w/){ it[1].toUpperCase() }
return delegate.get(key, delegate.get(alternate, 'Sorry...'))
}
def m = [myKey : 'Found your key']
assert 'Found your key' == m.customGet('myKey')
assert 'Found your key' == m.customGet('my_key')
assert 'Sorry...' == m.customGet('another_key')
println m
-结果-
m=[我的钥匙:找到你的钥匙,我的钥匙:找到你的钥匙,另一个钥匙:对不起…,另一个钥匙:对不起…]
在Tim的解决方案中,这导致m在第二个assert+2个键之后包含两个键,并带有默认值(对不起…),每次我们请求初始映射中不存在的新值时。。。这可以通过删除具有默认值的键来解决。e、 g:
Map.metaClass.customGet = { key ->
def alternate = key.replaceAll(/_\w/){ it[1].toUpperCase() }
def ret = delegate.get(key, delegate.get(alternate, 'Sorry...'))
if (ret == 'Sorry...') {
delegate.remove(key)
delegate.remove(alternate)
}
ret
}
请随意评论/更正可能导致的任何错误。。。在这里大声思考…我重新阅读了,我注意到get方法有两个版本。一个接受一个参数,另一个接受2
采用2的版本几乎与我在这里描述的一样:如果找不到您的密钥,它将返回一个默认值
我得到了想要的效果,但不是点符号,因此我只是将此作为一种替代方案发布,以防有人看到此帖子:
Map.metaClass.customGet = { key ->
def alternate = key.replaceAll(/_\w/){ it[1].toUpperCase() }
return delegate.get(key, delegate.get(alternate, 'Sorry...'))
}
def m = [myKey : 'Found your key']
assert 'Found your key' == m.customGet('myKey')
assert 'Found your key' == m.customGet('my_key')
assert 'Sorry...' == m.customGet('another_key')
println m
-结果-
m=[我的钥匙:找到你的钥匙,我的钥匙:找到你的钥匙,另一个钥匙:对不起…,另一个钥匙:对不起…]
在Tim的解决方案中,这导致m在第二个assert+2个键之后包含两个键,并带有默认值(对不起…),每次我们请求初始映射中不存在的新值时。。。这可以通过删除具有默认值的键来解决。e、 g:
Map.metaClass.customGet = { key ->
def alternate = key.replaceAll(/_\w/){ it[1].toUpperCase() }
def ret = delegate.get(key, delegate.get(alternate, 'Sorry...'))
if (ret == 'Sorry...') {
delegate.remove(key)
delegate.remove(alternate)
}
ret
}
请随意评论/更正可能导致的任何错误。。。在这里大声思考…我重新阅读了,我注意到get方法有两个版本。一个接受一个参数,另一个接受2
采用2的版本几乎与我在这里描述的一样:如果找不到您的密钥,它将返回一个默认值
我得到了想要的效果,但不是点符号,因此我只是将此作为一种替代方案发布,以防有人看到此帖子:
Map.metaClass.customGet = { key ->
def alternate = key.replaceAll(/_\w/){ it[1].toUpperCase() }
return delegate.get(key, delegate.get(alternate, 'Sorry...'))
}
def m = [myKey : 'Found your key']
assert 'Found your key' == m.customGet('myKey')
assert 'Found your key' == m.customGet('my_key')
assert 'Sorry...' == m.customGet('another_key')
println m
-结果-
m=[我的钥匙:找到你的钥匙,我的钥匙:找到你的钥匙,另一个钥匙:对不起…,另一个钥匙:对不起…]
在Tim的解决方案中,这导致m在第二个assert+2个键之后包含两个键,并带有默认值(对不起…),每次我们请求初始映射中不存在的新值时。。。这可以通过删除具有默认值的键来解决。e、 g:
Map.metaClass.customGet = { key ->
def alternate = key.replaceAll(/_\w/){ it[1].toUpperCase() }
def ret = delegate.get(key, delegate.get(alternate, 'Sorry...'))
if (ret == 'Sorry...') {
delegate.remove(key)
delegate.remove(alternate)
}
ret
}
请随意评论/更正可能导致的任何错误。。。在这里大声思考…你能举个例子说明这一点有用吗?也许我们可以想出一种方法,例如,当访问地图中不存在的密钥时,我想尝试获取另一个从缺少的密钥名称派生的密钥…例如,对于任何地图,如果密钥foo___________________________________________?也许我们可以想出一种方法,例如,当访问地图中不存在的密钥时,我想尝试获取另一个从缺少的密钥名称派生的密钥…例如,对于任何地图,如果密钥foo___________________________________________?也许我们可以想出一种方法,例如,当访问地图中不存在的密钥时,我想尝试从缺少的密钥名称中获取另一个密钥…例如,对于任何地图,如果密钥foo_bar