代码之家  ›  专栏  ›  技术社区  ›  Jack Guo

Kotlin联合多ELVIS操作员

  •  3
  • Jack Guo  · 技术社区  · 7 年前

    我正在分析一个火场 DataSnapshot (JSON)对象转换为数据类。如果其中任何一个为空,我可以组合它们并返回,而不是下面的内容吗?有点像雨燕 guard let ..., let ... else { return }

    func parse(snapshot: DataSnapshot) {
        val type = snapshot.child("type").value as? String ?: return
        val unitType = UnitEnumType.values().firstOrNull { it.abbrv == type } ?: return
        val imageUrl = snapshot.child("image_url").value as? String ?: return
        ...
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Marko Topolnik    7 年前

    val (type, unitType, imageUrl) = Triple(
        snapshot.child("type").value as? String ?: return,
        UnitEnumType.values().firstOrNull { it.abbrv == "a" } ?: return,
        snapshot.child("image_url").value as? String ?: return
    )
    

    但是,您不能引用 type (第一个表达式的结果)在第二个表达式中。这是一个完全或完全没有的任务。

        2
  •  0
  •   EpicPandaForce Jigar Joshi    7 年前

    我的意思是,从技术上讲,你可以设置一些疯狂的功能,比如:

    inline fun <A, R> guardLet(pairA: Pair<A?, (A) -> Boolean>, block: (A) -> R): R? {
        val (a, aPredicate) = pairA
        if(a != null && aPredicate(a)) {
            return block(a)
        }
        return null
    }
    
    inline fun <A, B, R> guardLet(pairA: Pair<A?, (A) -> Boolean>, pairB: Pair<B?, (B) -> Boolean>, block: (A, B) -> R): R? {
        val (a, aPredicate) = pairA
        val (b, bPredicate) = pairB
        if(a != null && b != null && aPredicate(a) && bPredicate(b)) {
            return block(a, b)
        }
        return null
    }
    

    称之为

    guardLet(someProperty to { it != "blah" }, otherProperty to { it.something() }) { somePropertyByCondition, otherPropertyByCondition ->
        ...
    } ?: return
    

    尽管在这种特殊情况下,您可以使用:

    inline fun <R, A> ifNotNull(a: A?, block: (A) -> R): R? =
        if (a != null) {
            block(a)
        } else null
    
    inline fun <R, A, B> ifNotNull(a: A?, b: B?, block: (A, B) -> R): R? =
        if (a != null && b != null) {
            block(a, b)
        } else null
    
    inline fun <R, A, B, C> ifNotNull(a: A?, b: B?, c: C?, block: (A, B, C) -> R): R? =
        if (a != null && b != null && c != null) {
            block(a, b, c)
        } else null
    
    inline fun <R, A, B, C, D> ifNotNull(a: A?, b: B?, c: C?, d: D?, block: (A, B, C, D) -> R): R? =
        if (a != null && b != null && c != null && d != null) {
            block(a, b, c, d)
        } else null
    

    和你一起去

    ifNotNull(
        snapshot.child("type").value as? String,
        UnitEnumType.values().firstOrNull { it.abbrv == type },
        snapshot.child("image_url").value as? String) { type, unitType, imageUrl -> 
        ...
    } ?: return
    

    我不知道,我只是在向你扔可能性。