Groovy - 仅可通过 getter-setter 追加到列表

Groovy - Appending to list available only via getter-setter

在 Groovy class 中,我想通过 getter 和 setter 公开内部 String 属性 作为 List。我希望 属性 的行为就像一个常规列表 属性,我可以使用 obj.list << newElement 添加元素。但是它不起作用,我必须使用变通方法 obj.list = obj.list << newElement.

在Groovy中还有其他方法可以做到这一点吗?要在 class 中实现的任何方法,将在使用 << 运算符时调用?

代码示例:

class Test {

    String internal = 'a,b,c'

    List getList() {
        return internal .split(',')
    }

    void setList(List list) {
        internal = list.join(',')
    }

}

def t = new Test()
println t.internal          // a,b,c
println t.list              // [a, b, c]
t.list << 'd'               // this does not work! does not add new element
println t.list              // [a, b, c] 
t.list = t.list << 'd'      // work-around that works
println t.list​​              // [a, b, c, d]

尝试使用以下代码,

Test t = new Test()
 List list = t.getList()
list << 'd'

println list.dump()

考虑以下几点:

class Test {
    String internal = 'a,b,c'

    List getList() {
        def list = internal.split(',') as List

        // this will override so:
        // << 'd'       becomes appendToList(['d'])
        // << ['e','f'] becomes appendToList(['e','f'])
        list.metaClass.leftShift = { def x ->
            this.appendToList([x].flatten())
        } 

        return list
    }

    void appendToList(List list) {
        internal = internal + "," + list.join(',')
    }

    void setList(List list) {
        internal = list.join(',')
    }
}

请注意,它处理 (a) 一个项目 (b) 项目列表的两种情况

def t = new Test()
t.list << 'd'
assert ['a','b','c','d'] == t.list
t.list << ['e','f']
assert ['a','b','c','d','e','f'] == t.list
t.list = ['x','y']
assert ['x', 'y'] == t.list