简体   繁体   English

如何使用布尔函数? Kotlin 中 if 语句中的返回类型

[英]how to use a function with Boolean? return type in an if statement in Kotlin

I'm using methods (for example the method containsKey of MutableList) that returns a true false.我正在使用返回真假的方法(例如 MutableList 的方法 containsKey)。 Since the function is written in java, Kotlin refers to return type as Boolean?由于函数是用java编写的,Kotlin将返回类型称为Boolean? and this the reason i'm getting a compilation error: "Required: Boolean, Found: Boolean?".这就是我收到编译错误的原因:“必需:布尔值,找到:布尔值?”。 I must say in some case (don't know why) using the method is ok and sometimes it return the error above.我必须说在某些情况下(不知道为什么)使用该方法是可以的,有时它会返回上面的错误。 Can someone guess what is the reason?有人能猜出是什么原因吗?

My code:我的代码:

val gamesPerCountriesMap = mutableMapOf<String,MutableMap<Long, List<AllScoresGameObj>>>()

if (countryName != null  && countryName != "" && !gamesPerCountriesMap.containsKey(countryName))
{
    gamesPerCountriesMap.put(countryName, mutableMapOf<Long,List<AllScoresGameObj>>())
}

if (!gamesPerCountriesMap.get(countryName)?.containsKey(competitionId))
{
    gamesPerCountriesMap.get(countryName)?.put(competitionId, listOf<AllScoresGameObj>())
}

First if is compiled the second one make the error:第一个 if 被编译第二个出错:

Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Boolean?在布尔类型的可为空的接收器上只允许安全 (?.) 或非空断言 (!!.) 调用?

if I remove the !如果我删除 in the beginning of the second if i will different error:在第二个开始时,如果我会出现不同的错误:

Type mismatch: inferred type is Boolean?类型不匹配:推断的类型是布尔值? but Boolean was expected但布尔值是预期的

After reading all the suggestion i wrote the following code:阅读完所有建议后,我编写了以下代码:

gamesPerCountriesMap.get(countryName)?.let {
    if (!gamesPerCountriesMap.containsKey(it))
    {
        gamesPerCountriesMap.get(countryName)?.put(competitionId, listOf<AllScoresGameObj>())
    }
}

What do you think?你怎么认为?

You have to take care of the nullable你必须照顾可空的

mutableMapOf<String?, MutableMap...

That means the keys can be a null String这意味着键可以是空字符串

If the countryName is a field, then如果countryName是一个字段,那么

countryName?.let {
   //your validation here
}

Fields can be changed so compiler doesn't know if it nullable or not.字段可以更改,因此编译器不知道它是否可以为空。

or或者

val safeName = countryName ?: return

Basically in the Java, Boolean is an object type.基本上在 Java 中,Boolean 是一种对象类型。 It has 3 possible values: true, false, and null.它有 3 个可能的值:true、false 和 null。 Since kotlin have null safety feature, using ?由于 kotlin 具有空安全功能,因此使用? in object type, like Boolean?, that's why it's asking you to make sure that the data isn't null.在对象类型中,例如 Boolean?,这就是为什么它要求您确保数据不为空。 So for your code:所以对于你的代码:

 if (!gamesPerCountriesMap.get(countryName)?.containsKey(competitionId))
                        {
                            gamesPerCountriesMap.get(countryName)?.put(competitionId, listOf<AllScoresGameObj>())
                        }

It checks if the get method returning null or not, if it's not, then it proceed to the next function containsKey .它检查get方法是否返回 null ,如果不是,则继续执行下一个函数containsKey If it's null, then it's pass the if statement.如果它为空,则通过 if 语句。 For the non-null asserted, it's force the Boolean?对于非空断言,它强制Boolean? data type into the Boolean .数据类型转化为Boolean This can be use if you're sure that the data must not be null, else it'll break your program, because you're accessing function in a null data.如果您确定数据不能为空,则可以使用它,否则它会破坏您的程序,因为您正在访问空数据中的函数。 So it depends on your choice, you can use ?所以这取决于您的选择,您可以使用? or !!或者!! if you sure it's not null.如果你确定它不为空。

if (!gamesPerCountriesMap.get(countryName)?.containsKey(competitionId))

will check if the item is true, false or null.将检查项目是否为真、假或空。 The "if" statement requires true or false. “if”语句要求为真或假。 This is why you see "Type mismatch: inferred type is Boolean? but Boolean was expected"这就是为什么您会看到“类型不匹配:推断类型为布尔值?但预期为布尔值”的原因

if (gamesPerCountriesMap.get(countryName) == null || !gamesPerCountriesMap.get(countryName)!!.containsKey(competitionId))

if the item is null, or if not null but also does not contain competitionID, then do this, so thats what you want to use.如果项目为空,或者如果不为空但也不包含竞争ID,则执行此操作,这就是您要使用的内容。

Edit:编辑:

You also want to allow the map to contain a null value like this:您还希望允许地图包含这样的空值:

val gamesPerCountriesMap = mutableMapOf<String,MutableMap<Long, List<AllScoresGameObj>>?>()

the "?"这 ”?” at the end allows the nested MutableMap to be null.最后允许嵌套的 MutableMap 为 null。

You can reduce it like:你可以像这样减少它:

if (!countryName.isNullOrEmpty()) {
    gamesPerCountriesMap.getOrPut(countryName) { mutableMapOf<Long,List<AllScoresGameObj>>() }
}

gamesPerCountriesMap[countryName]!!.getOrPut(competitionId) { listOf<AllScoresGameObj>() }

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

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