菊花链 Elvis 运算符?
Daisy Chaining Elvis Operators?
这有点丑:
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
逻辑显然不对,但是有没有接近于此的东西?或者做这么简单的事情需要一些严肃的狂热吗?
假设 hasParent = parent != null
和 hasPrev = prev != null
。
还假设 parent
和 prev
在 if
或 when
语句中定义为 val
,而不是 var
,因为我不喜欢添加!!
多次。
你正在做的是,使用 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
函数的组合(请参阅 Safe Calls 部分):
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
,return参数块中的最后一个表达式。
例如1.let { it + 2 }
就是3
.
如果 x
不为空,x?.let
执行 let
函数。
即 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
您可以在内部 let
函数中使用 it
进一步缩短它。
override var x1: Double = 0.0 //x-coordinate for object
get() =
parent?.let { pr -> (prev?.let { it.x2 } ?: 0) + pr.mEventSpacing } ?: field
此外,您可以使用 run
和 let
的组合。 (Google 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
是最容易理解的
嗯,如果 parent
和 prev
被定义为 var
,使用 when
表达式和 !!
可以引发 NPE,而使用 ?.let
、?.run
和 ?:
永远不会在多核设备中引发 NPE。为防止这种情况,您可以使用 getter 函数中的当前值定义局部 val
s,这样您就永远不需要使用 !!
运算符。
这有点丑:
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
逻辑显然不对,但是有没有接近于此的东西?或者做这么简单的事情需要一些严肃的狂热吗?
假设 hasParent = parent != null
和 hasPrev = prev != null
。
还假设 parent
和 prev
在 if
或 when
语句中定义为 val
,而不是 var
,因为我不喜欢添加!!
多次。
你正在做的是,使用 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
函数的组合(请参阅 Safe Calls 部分):
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
,return参数块中的最后一个表达式。
例如1.let { it + 2 }
就是3
.
x
不为空,x?.let
执行 let
函数。
即 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
您可以在内部 let
函数中使用 it
进一步缩短它。
override var x1: Double = 0.0 //x-coordinate for object
get() =
parent?.let { pr -> (prev?.let { it.x2 } ?: 0) + pr.mEventSpacing } ?: field
此外,您可以使用 run
和 let
的组合。 (Google 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
是最容易理解的
嗯,如果 parent
和 prev
被定义为 var
,使用 when
表达式和 !!
可以引发 NPE,而使用 ?.let
、?.run
和 ?:
永远不会在多核设备中引发 NPE。为防止这种情况,您可以使用 getter 函数中的当前值定义局部 val
s,这样您就永远不需要使用 !!
运算符。