0

我们以类型安全的方式使用 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

有没有一种从字符串创建 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
)
4

2 回答 2

1

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

考虑将方法重新定义为:

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

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


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

void fooWrapper (String baa) {
    foo(baa + "${''}")
}
于 2022-01-05T14:59:02.547 回答
0

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


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)
    }
}
于 2022-01-05T14:40:01.050 回答