2

这有点丑:

override var x1: Double = 0.0 //x-coordinate for object
    get() =
        if(hasParent) { //if there is no parent, we can't have an x coord anyway - nowhere to draw this object
            if (hasPrev) { //we won't always have a previous event, thus the other branch
                prev!!.x2 + parent!!.mEventSpacing
            } else {
                parent!!.mEventStartX
            }
        } else {
            field
        }

是否可以用以下内容替换它?

override var x1: Double = 0.0
    get() = (prev?.x2 + parent?.mEventSpacing) ?: parent?.mEventStartX ?: field

逻辑显然不正确,但有什么接近这个的吗?还是需要一些认真的摆弄才能做这么简单的事情?

4

1 回答 1

2

假设hasParent = parent != nullhasPrev = prev != null
还假设parentandprev被定义为val,而不是variforwhen语句中,因为我不喜欢!!多次添加。

你正在做的是,使用when表达式:

override var x1: Double = 0.0 //x-coordinate for object
    get() = when {
        parent != null && prev != null -> prev.x2 + parent.mEventSpacing
        parent != null && prev == null -> parent.mEventSpacing
        parent == null -> field
    }

您可以使用?.运算符和let函数的组合(请参阅安全调用部分):

override var x1: Double = 0.0 //x-coordinate for object
    get() =
        parent?.let { pr -> prev?.let { pv -> pv.x2 + pr.mEventSpacing } ?: pr.mEventSpacing } ?: field

let函数执行参数是被调用的参数块let,并返回参数块中的最后一个表达式。

例如,1.let { it + 2 }3

x?.let如果不为空则执行let函数。x即,x?.let { ... }与 相同if (x != null) x.let { ... } else null)

这里,

如果parent == null, 那么
parent?.let { pr -> prev?.let { pv -> pv.x2 + pr.mEventSpacing } ?: pr.mEventSpacing }就是null.

如果parent != null, 那么
parent?.let { pr -> prev?.let { pv -> pv.x2 + pr.mEventSpacing } ?: pr.mEventSpacing }prev?.let { pv -> pv.x2 + parent!!.mEventSpacing } ?: parent!!.mEventSpacing

你可以缩短这个。如果prev == null,则prev.x2可以视为0。所以

override var x1: Double = 0.0 //x-coordinate for object
    get() =
        parent?.let { pr -> (prev?.let { pv -> pv.x2 } ?: 0) + pr.mEventSpacing } ?: field

您可以通过it在内部let函数中使用来进一步缩短它。

override var x1: Double = 0.0 //x-coordinate for object
    get() =
        parent?.let { pr -> (prev?.let { it.x2 } ?: 0) + pr.mEventSpacing } ?: field

此外,您可以使用run和的组合let。(谷歌kotlin run或者kotlin run vs let如果你不知道的话。)

override var x1: Double = 0.0 //x-coordinate for object
    get() =
        parent?.run { (prev?.let { it.x2 } ?: 0) + mEventSpacing } ?: field

但我认为使用when是最容易理解的。


好吧,如果parentprev被定义为var,使用when表达式 with!!可以引发 NPE,而使用?.let,?.run?:永远不会在多核设备中引发 NPE。为了防止这种情况,您可以val使用 getter 函数中的当前值定义 local s,这样您就永远不需要使用!!运算符。

于 2018-07-26T04:30:44.843 回答