Groovy:构造函数问题

Groovy:构造函数问题,groovy,Groovy,如果我有这样一门课: class Person { def name def greeting = "hello $name" } 我打电话 鲍勃=新人(姓名:“鲍勃”) 当我在这一点上检查Bob时,我看到问候语中没有“Bob”。我做错了什么?构造函数调用发生在对象初始化之后。换句话说,问候语值是在调用构造函数之前设置的 如果您想做您正在做的事情,您需要一个构造函数,它将名称作为参数,并将问候语分配给“hello:${name}” 另外,我不太确定参数赋值(名称:“bob”)是否发生在构造函

如果我有这样一门课:

class Person { 
def name
def greeting = "hello $name"
}
我打电话 鲍勃=新人(姓名:“鲍勃”)


当我在这一点上检查Bob时,我看到问候语中没有“Bob”。我做错了什么?

构造函数调用发生在对象初始化之后。换句话说,问候语值是在调用构造函数之前设置的

如果您想做您正在做的事情,您需要一个构造函数,它将名称作为参数,并将问候语分配给“hello:${name}”


另外,我不太确定参数赋值(名称:“bob”)是否发生在构造函数之后或构造函数内部,其他人可能会回答这个问题。

我会这样实现它

class Person { 
    def name
    String getGreeting() {"hello $name"}
}
这样,问候语仍然是一个属性,您可以像这样引用它

def bob = new Person(name: 'Bob')

println bob.greeting
你可以绕开这个问题

class Person { 
  def name
  @Lazy def greeting = "hello $name"
}

bob = new Person(name: "bob")
println bob.greeting
将根据需要打印
hello bob
。注释更改了问候语的getter,以便只在第一次调用它时生成它(然后缓存结果)。这样做的副作用是,一旦调用一次,就会使
问候语
保持静态,但您不会说是否需要随时间而更改(由于
名称
更改)。。。ie

bob = new Person(name: "bob")
println bob.greeting
bob.name = 'dave'
println bob.greeting
将打印:

hello bob
hello bob

您能为#name添加setter吗?如果您定义了一个,Groovy将调用它

class Person { 
    def name
    def greeting = "hello"

    void setName(final val) { name = val; greeting = "hello $name" }
}

final o = new Person(name:"bob")
assert o.greeting == "hello bob"

据我所知,新人(姓名:“鲍勃”)=
personp=newperson();p、 setName(“bob”)
在GroovySteen中,感谢您的回答。如果我无法控制编写一个新的构造函数(在Grails中处理一个服务类),那么除了在问候语之前强制设置名称,我还有什么选择呢?或者重写问候语?也许您可以将Person用作普通的DTO,并在此类之外计算问候语。这里的缺点可能是每次调用getGreeting()时都会计算问候语本身(以及名称)。我的实际示例稍大一些,创建了一个我希望设置一次而不是再次计算的映射。@Dmitry I关于
@Lazy
注释的信息,如果我正确理解您的意思,它可能适合您!我用我的大地图测试了一下,效果很好。是的,我只想实例化一次。这里的用例是在Grails服务类中定义的访问控制矩阵(因此是一个单例)。对于我的用例,我非常喜欢@Lazy选项。