我试图理解如下定义的自定义private fun toggleView1Visibility() {
TransitionManager.endTransitions(sceneRoot)
val isView1Appearing = view1.visibility != View.VISIBLE
TransitionManager.beginDelayedTransition(
sceneRoot,
createTransition(isView1Appearing)
)
view1.visibility = if (isView1Appearing) View.VISIBLE else View.GONE
}
private fun createTransition(
isView1Appearing: Boolean
): Transition {
val view1Fade = Fade().apply {
addTarget(view1)
duration = 750
}
val view2ChangeBounds = ChangeBounds().apply {
addTarget(view2)
duration = 750
}
return TransitionSet().apply {
ordering = TransitionSet.ORDERING_SEQUENTIAL
if (isView1Appearing) {
addTransition(view2ChangeBounds)
addTransition(view1Fade)
} else {
addTransition(view1Fade)
addTransition(view2ChangeBounds)
}
}
}
约束,
core.logic
如何在(defne lefto
"x appears to the left of y in collection l."
[x y l]
([_ _ [x . tail]] (membero y tail))
([_ _ [_ . tail]] (lefto x y tail)))
的上下文中解释_
和.
?
答案 0 :(得分:2)
defne
是使用特殊模式匹配语法的宏,但其行为与conde
类似。 (仅供参考,其中每个e
代表“一切”,即每个子句都可以做出贡献。)
_
下划线表示必须存在的值,但是您不在乎它是什么。.
表示项目在.
左侧,列表的尾部在.
右侧。这用于将列表的各个项目和列表的其余部分绑定到不同的值。 (另请参见core.logic中的llist
。) Clojure中类似的序列破坏操作将使用&
而不是.
:
(let [[_ _ [_ & tail]] coll] ...)
因此以下模式的意思是“我们不在乎第一个或第二个输入参数,但第三个应该是列表,其中我们的头是x
(即等于函数的x
输入参数),然后将尾部绑定到tail
“:
[_ _ [x . tail]]
还请注意,tail
在此处可以为空列表,并且您可以在.
之前绑定多个值。
由于您的示例是递归目标,因此它最终会通过在x
之前找到y
而终止,或者由于l
将(最终)成为空列表()
,这两种情况都不匹配。
membero
定义本身是相同想法的一个简单示例:
(defne membero
"A relation where l is a collection, such that l contains x."
[x l]
([_ [x . tail]])
([_ [head . tail]]
(membero x tail)))
有两个子句,每个子句都由顶级列表()
表示:
[_ [x . tail]]
-第一个_
代表输入x
arg,我们不在乎 match 。 [x . tail]
描述了第二个参数l
的模式,其中如果x
是l
的头,则此模式匹配并且membero
成功。[_ [head . tail]
-_
在这里的含义相同。但是请注意,我们已经为l
的头添加了一个新名称,只需要将其命名为非空列表即可满足此模式。如果匹配,则我们以(membero x tail)
递归继续搜索。只有第一个子句可以通过在x
的(子)列表中找到l
来使目标成功。第二个子句仅用于解构head
的{{1}}和tail
并递归。
此处l
的翻译为membero
,但没有模式匹配:
conde