在 Kotlin 中检查表达式是否为 null,类似 Lua?
2019-10-26 22:3:28
收藏:0
阅读:85
评论:2
在 Lua 中(在 Corona SDK 开发之外很少使用),您可以使用以下方式在 if 语句中评估 ANY 表达式:
- 如果表达式为 null,则返回
false - 如果表达式是布尔值
false,则返回false - 其他情况将返回
true
举例
if (1) // true
if ("Hello World") // true
if (instanceOfSomeRandomClass) // true
if ( [2, null, "foo"] ) // true
if (thisFunctionCallWithReturnNull()) // false
if (0 == 1) // false
在 Kotlin 中,if 也恰好是一个表达式,因此可以组合这些特性,我可以想到很多创造性的使用方式。
在 Kotlin 中是否有等效的方法?
我知道您可以始终手动检查 if (expression != null),这样做没有问题,但 if (expression) 更加“懒惰”,我喜欢偷懒 :)
点赞
用户10536125
为了更方便,你可以创建一个高阶 luaIf 函数:
sealed class LuaIf<T> {
class True<T>(val value: T) : LuaIf<T>()
object False : LuaIf<Nothing>()
}
inline fun <T> luaIf(condition: Any?, block: () -> T): LuaIf<T> =
if (condition == null || condition == false) False as LuaIf<T>
else True(block())
inline infix fun <T : R, R> LuaIf<T>.els(ifFalse: () -> R): R = when (this) {
is True -> value
False -> ifFalse()
}
并且可以像这样使用它:
luaIf(null) { 1 } els { 0.5 } // 0.5
luaIf(Any()) { 1 } els { 0.5 } // 1
不幸的是,每当条件为 true(或不为 null)时,就会创建一个 LuaIf.True 实例。你可以通过内联 LuaIf 类来进行优化:
inline class LuaIf<T> @Deprecated(
message = "Not type-safe, use factory method",
replaceWith = ReplaceWith("luaIf(true) { _value }", "package.file.luaIf")
) constructor(val _value: Any?)
object LuaIfFalse
inline fun <T> luaIf(condition: Any?, ifTrue: () -> T): LuaIf<T> =
if (condition == null || condition == false) LuaIf(LuaIfFalse)
else LuaIf(ifTrue())
inline infix fun <T : R, R> LuaIf<T>.els(ifFalse: () -> R): R =
if (_value == LuaIfFalse) ifFalse()
else _value as T
现在,如果你查看 println(luaIf(nullableAny) { 1 } els { 0.5 }) 的字节码,你将看不到任何额外的对象被创建。下面是我反编译的字节码:
Object $this$els$iv = LuaIf.constructor-impl(
nullableAny != null && !Intrinsics.areEqual(nullableAny, false) ? 1 : LuaIfFalse.INSTANCE
);
System.out.println(
Intrinsics.areEqual($this$els$iv, LuaIfFalse.INSTANCE) ? 0.5 : $this$els$iv
);
public final class LuaIf {
public static Object constructor-impl(@Nullable Object _value) {
return _value;
}
}
但由于内联类是实验性的,如果你以奇怪的方式使用它们,它们可能会导致一些错误。例如,以下代码将引发 ClassCastException: Integer cannot be cast to LuaIf:
falseLua { luaIf(0) { 0 } } els { 0 }
fun <T> falseLua(other: () -> T): T = luaIf(false) { error("Impossible") } els other
我已经在 Stack Overflow 上询问了这个异常。
2019-10-27 12:10:51
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

引用 Kotlin 语言规范:
因此,不,Kotlin 中没有直接的等效方法。
不过,您可以通过在
Any?上使用自定义的 扩展函数 来模拟该行为:fun Any?.toBoolean() = this != null && this != false在下方代码中可以看到它的效果(请注意
input.toBoolean()):fun main() { evaluate(1) evaluate("Hello World") evaluate(String()) evaluate(listOf(2, null, "foo")) evaluate(null) evaluate(0 == 1) } fun evaluate(input: Any?) { println("$input is ${input.toBoolean()}") }输出结果为:
1 is true Hello World is true is true [2, null, foo] is true null is false false is false但我不确定这是否就足以证明它更 "节懒"。