为什么这种行为使用 Object.with 方法与 Object(name:name) 进行属性分配

Why this behavior using Object.with method vs Object(name:name) for attribute assignment

在实例化新对象时使用我认为类似于属性赋值形式的行为时,我遇到了两种不同类型的行为。

语言是 Groovy

当我运行这个使用 with 的方法时,id 从未设置并保持为空。所有其他属性都已正确设置。

def newSubFnObj( row, id ) {
    def sf = new SubFunction()
    sf.with {
        function    = row.PGM_PROC_FUNC
        subfunction = row.PGM_PROC_SUBF
        name        = getFunctionName( row )
        level       = row.PGM_PROC_LEVEL
        id          = id
    }
    return sf
}

但是,当我使用此方法时,id 设置正确,我没有遇到任何问题。

def newSubFnObj( row, id ) {
    def sf = new SubFunction(function   :row.PGM_PROC_FUNC,
                             subfunction:row.PGM_PROC_SUBF,
                             name       :getFunctionName( row ),
                             level      :row.PGM_PROC_LEVEL,
                             id         :id)
    return sf
}

为了彻底起见,此方法也具有正确的行为。

def newSubFnObj( row, id ) {
    def sf = new SubFunction()
    sf.function    = row.PGM_PROC_FUNC
    sf.subfunction = row.PGM_PROC_SUBF
    sf.name        = getFunctionName(row)
    sf.level       = row.PGM_PROC_LEVEL
    sf.id          = id
    return sf
}

这是出于上下文目的的第三个相关方法。

def setParentChildInformation( subfunctions ) {
    subfunctions.eachWithIndex { s, i ->
        if ( i > 0 ) {
            def parentNotFound = true
            def x = i
            while ( parentNotFound && x >= 0 ) {
                x--
                def possibleParent = subfunctions[x]
                if ( s.levelNumber > possibleParent.levelNumber ) {
                    parentNotFound = false
                    possibleParent.childSubfunctions << s.id
                    s.parentId = possibleParent.id
                }
            }
        }
    }
}

另一种用于上下文目的的方法。

def getFunctionName( row ) {
    return "${row.PGM_PROC_FUNC}${row.PGM_PROC_SUBF}".toString()
}

这是 SubFunction 类的代码

class SubFunction {
    def id
    def parentId
    def name 
    def function
    def subfunction
    def level
    def levelNumber
    def rows = []
    def lines = []
    def statements = []
    def childSubfunctions = []
}

我不太关心哪种做事方式更好。使用 with 是在对象内执行属性分配的一种更常规的方式。我只是想阐明为什么会发生这种行为。

只需将参数重命名为 id 以外的其他名称。

原因似乎很明显。 with(Closure) 的闭包 arg 将委托设置为 SubFunction,因此它将 id 视为对象(为空)的对象,而不是将 id 作为参数传递给 newSubFnObj()方法。

def newSubFnObj( row, _id ) {
    def sf = new SubFunction()
    sf.with {
        function    = row.PGM_PROC_FUNC
        subfunction = row.PGM_PROC_SUBF
        name        = getFunctionName( row )
        level       = row.PGM_PROC_LEVEL
        id          = _id
    }
    return sf
}

上面应该做的。