简体   繁体   English

Kotlin Val任务

[英]Kotlin val assignment

Ran into this and wanted to do this with the least amount of repetitive code. 碰到这一点,并希望用最少的重复代码来做到这一点。 In Java I would do it this way (being an old Java programmer). 在Java中,我会以这种方式(作为一个古老的Java程序员)这样做。 For reference, data is a Map<String, String> . 作为参考, dataMap<String, String>

Class action = SomeActivity.class;
if (data != null && data.get("abc") != null) {
    if (data.get("abc").contains("details")) {
        action = OtherActivity.class;
    } ... //may have more ifs for other contains()
}

Intent newIntent = new Intent(this, action);

I wanted to do the same in Kotlin but not repeat null conditions and use multiple assignment lines. 我想在Kotlin中做同样的事情,但不重复空条件并使用多条分配行。 This is what I have so far. 到目前为止,这就是我所拥有的。

val action = data["abc"]?.let {
    if (it.contains("details")) {
        OtherActivity::class.java
    } else {
        SomeActivity::class.java
    }
} ?: kotlin.run { SomeActivity::class.java }

val intent = Intent(this, action)

To me the Java looks more efficient than Kotlin here, with Kotlin I have two assignment lines repeated the SomeActivity::class.java , whereas in Java I can set the variable to one class and if and only if all the null and if condition checks out will it assign the new class. 对我来说,Java在这里看起来比Kotlin更有效,在Kotlin中,我有两条赋值行重复SomeActivity::class.java ,而在Java中,我可以将变量设置为一个类,并且当且仅当所有null和if条件检查时它将分配新的班级。 So is there a way to do this in Kotlin without repeated assignment lines for SomeActivity::class.java ? 那么有没有办法在Kotlin中做到这一点而无需为SomeActivity::class.java重复分配行?

For the provided code, the following should work: 对于提供的代码,以下内容应该起作用:

val intent = Intent(this, 
   data?.takeIf { it["abc"]?.contains("details") == true }
       ?.let { OtherActivity::class.java } 
       ?: SomeActivity::class.java
)

If you have additional branches, then of course you should use a when statement. 如果您还有其他分支,那么您当然应该使用when语句。

val abc = data?.get("abc")

val action = when {
    abc == null -> SomeActivity::class.java
    abc.contains("details") -> OtherActivity::class.java
    // other branches
    else -> SomeActivity::class.java
}
val intent = Intent(this, action)

Maybe something like the following will work for you: 也许以下内容将为您工作:

val action = if (data?.get("abc")?.contains("details") == true) {
    OtherActivity::class.java
} else SomeActivity::class.java
val intent = Intent(this, action)

Note, you need the == true because the left part of the condition may still be null in which case the condition will result to: null == true , which then basically just returns the SomeActivity::class.java . 请注意,您需要== true因为条件的左侧部分可能仍然为null在这种情况下,条件将导致: null == true ,然后基本上只返回SomeActivity::class.java

If you like ~one liners or when : 如果您喜欢〜一个衬垫或when

val intent = Intent(this, when {
  data?.get("abc")?.contains("details") == true -> OtherActivity::class.java
  /* Other conditions */ 
  else -> SomeActivity::class.java
})

Finally you could also just use the same construct as you had in Java by using var instead and specifying your general type, eg: 最后,您还可以使用与Java中相同的构造,方法是使用var并指定常规类型,例如:

var action : Class<*> = SomeActivity::class.java
if (data?.get("abc")?.contains("details") == true) { 
  // Or add the conditions you actually had
  action = OtherActivity::class.java
}
Intent newIntent = new Intent(this, action);

You can use a when block to do it neatly: 您可以使用when块来巧妙地做到这一点:

val abc = data["abc"]
val action = when {
    abc == null -> OtherActivity::class.java
    abc.contains("details") -> DetailsActivity::class.java
    abc.contains("somedata") -> SomeActivity::class.java
    abc.contains("otherdata") -> UnknownActivity::class.java
    else -> DefaultActivity::class.java
}

Or without repeating variable name: 或不重复变量名:

val action = data["abc"].run {
    when {
        this == null -> OtherActivity::class.java
        contains("details") -> DetailsActivity::class.java
        contains("somedata") -> SomeActivity::class.java
        contains("otherdata") -> UnknownActivity::class.java
        else -> DefaultActivity::class.java
    } 
}

Or if you can afford to use equals instead of contains: 或者,如果您有能力使用equals代替contains:

val action = when(abc) {
    null -> OtherActivity::class.java
    "details" -> DetailsActivity::class.java
    "somedata" -> SomeActivity::class.java
    "otherdata" -> UnknownActivity::class.java
    else -> DefaultActivity::class.java
}

Note that catching null as the first case lets other branches smart-cast to non-nullable type. 请注意,在第一种情况下捕获null将使其他分支智能广播为不可为null的类型。

You do this in this way 您以这种方式进行

    val action = data["abc"]?.let {
        if (it.contains("details")) OtherActivity::class.java
            else SomeActivity::class.java
    }

    val intent = Intent(this,action)

if data["abc"] is null the let block is not called. 如果data [“ abc”]为null,则不调用let块。 so you can do this. 所以你可以做到这一点。

prevent null assignment (if deta["abc" 防止分配空值(如果deta [“ abc”

   val action= data["abc"]?.let {
        if (it.contains("details")) OtherActivity::class
            else SomeActivity::class
    } ?: DefaultActivity::class

    val intent = Intent(this,action.java)

You can use when , and an intermediate null to not repeat the else branch. 您可以使用when和中间的null来不重复else分支。

val action: KClass<out Activity> = data?.get("abc")?.let {
   when {
     it.contains("details") -> OtherActivity::class
     it.contains("bla")     -> BlaActivity::class
     else                   -> null
  }
} ?: SomeActivity::class

val intent = Intent(this, action.java)

Note that data["abc"] will not work if data can be null! 需要注意的是data["abc"]如果行不通的data可以为空!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM