最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

從 Minecraft 插件開發(fā)認(rèn)識 Kotlin Contract

2023-03-18 02:08 作者:閑蛋不太閑  | 我要投稿

用 Kotlin 來寫 Minecraft 插件是讓人爽到喝水太多想尿尿的。舉個例子,你可以給 ItemStack 定義一個擴(kuò)展方法 (Extension Function)。

我們不用繼承該類或者使用張三李五變形金剛設(shè)計模式,也不用單獨(dú)創(chuàng)建一個 XXXUtils.class 即可實現(xiàn)原始類的擴(kuò)展。

現(xiàn)在有個需求,我們要兼容 Nullable ItemStack 的判斷 (即 ItemStack?)。因為有的時候我們拿到的 ItemStack 是 Null,很多情況會導(dǎo)致這樣,包括我們在箱子內(nèi) getSlot(integer) 拿物品和部分超級我的世界插件開發(fā)者用 Java 寫返回值接口的時候不會表 @NotNull。

這也是很容易改寫的:

但現(xiàn)在問題來了:

在 ItemStack?.isAir() 擴(kuò)展方法中,我們進(jìn)行了判空操作。當(dāng)返回值為 false 時就足以確認(rèn) ItemStack 不為 null,但 Kotlin 的編譯器不知道這一點,它無法從這個方法內(nèi)得到這個信息,如果要想過編譯我們必須使用 item!!.type 或 item?.type,這使用起來太痛苦了,比 LexBurner 釋放忍術(shù)還要痛苦。

問題在于 Kotlin 的編譯器不知道這一信息,那我們是否可以手動提供給它來幫助推斷?我們可以:

這就是 Kotlin 的契約 (Contract),它在 1.3 版本當(dāng)中作為實驗特性被添加進(jìn)來,還有幾個變體但都大同小異,這里就不一一介紹。

還有一個契約被稱為 callsInPlace,舉個例子:

在上面的代碼同樣出現(xiàn)了 “編譯器不知道更多信息” 導(dǎo)致編譯時期出現(xiàn)錯誤的情況,以編譯器的視角來看的話:

  • 如果 block 這個參數(shù)在 run 方法沒有被執(zhí)行,就會出現(xiàn) item 未初始化的情況。

  • 如果 block 這個參數(shù)在 run 方法被執(zhí)行了多次,item 就會被多次賦值,而 val 聲明的變量是不允許多次賦值的。

使用 callsInPlace 讓它能正常跑起來:

在 Kotlin 的標(biāo)準(zhǔn)庫內(nèi)也大量使用了 Contract,例如 let、also、run 等等,我在最近才認(rèn)識學(xué)習(xí)了這個特性,作為一直寫 Kotlin 的這丟人到頂了。

垃圾話

Kotlin 的 Contract 有點類似于莆田版 Refinement Type,用我這種笨蛋垃圾廢物能理解的話就是說:

如果普通的類型指定了值的取值范圍或集合(例如 Integer 為 [-2^31,2^31-1]),那么 Refinement Type 即可以看作指定這個集合的子集。用 Scala 的?refined?庫舉個例子:

i2 在賦值的時候數(shù)值并不滿足 Positive (即 >= 0) 的 Predicate,所以在編譯時拋出了錯誤。

目前僅有一些非常牛逼且冷門的語言支持了原生的 Refinement Type,例 F*,但例如像 Scala,Haskell 這類語言也有 Refinement Type 的第三方庫,好像 TypeScript 也有,但我沒了解過。

隨著 K2 Compiler 的完工,Kotlin 官方有想重新設(shè)計 Contract 語法的意思。你可以在 https://github.com/Kotlin/KEEP/issues/139 看到一些跡象。

我覺得用 B 站專欄寫技術(shù)文章的人用 Java 寫返回值接口的時候不會表 @NotNull 的人一樣抽象,但這篇文章很水不想掛博客和知乎所以我掛在這里。

從 Minecraft 插件開發(fā)認(rèn)識 Kotlin Contract的評論 (共 條)

分享到微博請遵守國家法律
宝应县| 故城县| 革吉县| 多伦县| 全州县| 苏尼特左旗| 张家川| 龙井市| 金溪县| 五台县| 衡水市| 大理市| 峨眉山市| 曲周县| 永康市| 佛学| 鲁山县| 乐业县| 佳木斯市| 聂拉木县| 清徐县| 定兴县| 葫芦岛市| 新丰县| 额敏县| 化德县| 霸州市| 阜宁县| 垫江县| 万宁市| 敦化市| 长武县| 宜黄县| 玉树县| 西乌| 纳雍县| 永兴县| 新竹市| 六枝特区| 祁东县| 大安市|