从字符串创建 GString

Create GString from String

我们正在以类型安全的方式使用 groovy。在某些时候我想调用一个带有签名的方法

void foo(GString baa)

只要我输入的字符串包含一些${baz}一切都很好,但是当我使用纯字符串时出现编译错误

foo("Hello, ${baz}") // fine
foo("Hello, world") // Cannot assign value of type java.lang.String to variable of type groovy.lang.GString
foo("Hello, world${""}") // fine but ugly

是否有从 String 创建 GString 的好方法?

编辑

我想我把问题简单化了。我正在使用命名构造函数参数来初始化对象。由于某些字符串是延迟计算的,因此我需要将它们存储为 GString.

class SomeClass {
  GString foo
}

new SomeClass(
  foo: "Hello, world" // fails
)

所以方法重载是没有选择的。

willyjoker 提到的解决方案是使用 CharSequence 而不是 String

class SomeClass {
  CharSequence foo
}

new SomeClass(
  foo: "Hello, world" // works
)

new SomeClass(
  foo: "Hello, ${baa}" // also works lazily
)

您可以创建重载方法,也可以使用泛型;如下所示:


foo("Hello from foo GString ${X}")
foo("Hello from foo")

MyClass.foo("Hello from foo GString ${X}")
MyClass.foo("Hello from foo")

// method with GString as parameter
void foo(GString g) {
    println("GString: " + g)
}

// overloading method with String as parameter
void foo(String s) {
    println("String: " + s)
}

// using generics
class MyClass<T> {
    static void foo(T t) {
        println(t.class.name + ": " + t)
    }
}

可能没有充分的理由让方法只接受 GString 作为输入或输出。 GString 旨在作为常规字符串互换使用,但具有延迟计算的嵌入值。

考虑将方法重新定义为:

void foo (String baa)
void foo (CharSequence baa)  //more flexible

通过这种方式,该方法同时接受 String 和 GString(GString 参数会根据需要自动转换为 String)。第二个版本甚至接受 StringBuffer/Builder/etc.


如果您绝对需要保留 GString 签名(因为它是第三方 API,等等),请考虑创建一个包装器方法,它接受 String 并执行内部转换。像这样:

void fooWrapper (String baa) {
    foo(baa + "${''}")
}