1. Jieshao
Dang wo men xie yige 함수/han shu (function) shi, tongchang hui xiang: “Ta jie shou can shu bing fanhui jieguo”. Dan xianshi hen kuai jiu lai chazai, bing dai lai “liwu”: “shuru bu shi shu zi”, “zhao bu dao”, “caozuo bu keneng”, “wenjian da bu kai”, “zhuangtai huai le”. Ran hou, chengxu kai fa de “chengren bufen” jiu kaishi le: ni xuyao xian shuo hao, han shu yao ruhe tongzhi cuowu.
Zhe ge yueding jiu jiao zuo cuowu hetong: naxie qingkuang suan cuowu, naxie shi keyi yujian de, yi ji ta men ying gai yi shenme xingshi fanhui gei diaoyong fang.
Hetong hen zhongyao, yinwei mei you ta, daima jiu hui “kan xinqing” yunxing. Zai mou yige difang ni fanhui null, ling yige difang ni diu yichang, di san ge difang ni da yin println("Error") ran hou ji xu zou, hao xiang shenme dou mei fasheng. Zhe zhong xingwei zai da xing chengxu li tebie weixian: cuowu bu shi bei “cang” qilai, jiu shi zai hen wan, hen guai de difang cai “maochulai”.
You yige zhide jilu de guandian: cuowu bu shi “zhi shi beng le”。Cuowu shi yi zhong qingkuang: han shu wu fa fulu (fulfill) ta hetong li de chengnuo.
2. Chuan da cuowu de zhuyao fangshi
Dang ni xuanze cuowu chuli celue shi, you liang ge zhuyao gongju: yichang he cuowu zuowei zhi.
Yichang
Yichang hui zhongduan zhengchang de zhixing liu: “wo bu neng jixu, rang wai mian de ren lai jueding”. Zhe shi yi ge hen qiang de ji zhi, dan ta hen xiang xiaofang jingbao: zhen de fasheng huozai shi hen bang, dan ru guo ni yong ta lai tongzhi “tang yong wan le” jiu hen guai.
“Cuowu zuowei zhi”
“Cuowu zuowei zhi” yiwei zhe han shu fanhui de bu zhi shi “chenggong”, ye bao han “shibai” de putong fanhui zhi. Wo men zhi qian yi jing yong sealed class he Ok / Error bianzhong zuo guo zhe yang de shi: diaoyong fang bixu kan qingchu fanhui le shenme, ran hou chuli.
Ke yi zhe yang lai xiangxiang ta men de chabie:
flowchart TD
A[Call function] --> B{What happened?}
B -->|Success| C[Returned a value]
B -->|Expected problem| D[Returned Error as a value]
B -->|Crash or logical impossibility| E[Threw an exception]
Zhe li de guanjian dian shi: zai D he E zhi jian zuo xuanze, bu shi “na ge geng rongyi xie”, er shi zhe ge qingkuang de yiyi shi shenme.
3. Fail-fast jiancha: require(...) he check(...)
Kotlin ti gong le feichang fangbian de fail-fast gongju: require(...) he check(...)。Ta men kan qilai hen xiang, dan yiyi bu tong.
require(...): wenti zai shuru can shu
Changjian qingkuang: han shu jie shou can shu, ni shi xian jiu zhidao you xie zhi shi meiyou yiyi de. Li ru, dang total = 0 shi suan “zhan zongliang de baifenbi”, huo zhe “zhichu jine” xiao yu 0. Zhe bu shi zhengchang liucheng de fen zhi,er shi han shu bei cuowu diaoyong.
Zhe zhong difang zui he shi yong require(...): ta jiancha qianzhi tiaojian, ru guo bu manzu, jiu diu chu “can shu bu hefa” xiang guan de yichang.
Mini shili:
fun percent(part: Int, total: Int): Int {
require(total > 0) { "total must be > 0, got $total" }
require(part >= 0) { "part must be >= 0, got $part" }
return part * 100 / total
}
fun main() {
println(percent(2, 5)) // 40
}
Qing zhuyi xia xiaoxi (message) de fengge: wo men bu xie “aiya”, bu xie “cuowu”, er shi xie chu qidai he shiji zhi: got ...。Zhe hui sheng xia hen duo diaoshi shijian, tebie shi dang ni wang le zi ji xie guo zhe ge han shu, yi ge yue hou (ye jiu shi ming tian) you hui tou kan de shi hou.
Yao mingbai require de zhexue: ta bu shi “cuowu chuli”, er shi jinzhi jixu,yinwei shuru bu fuhe hetong. Ye jiu shi shuo, wo men bu shi xiang “xiang banfa ying fu” bu hefa can shu—wo men zhi jie shuo: “zhe yang bu xing”.
check(...): wenti zai zhuangtai
Ru guo shuo require(...) shi “diaoyong fang gei le huai can shu”, na me check(...) jiu shi “chengxu nei bu de zhuangtai bian de bu dui, zhe bu ying gai fasheng”. Zhe geng xiang shi bug: mouchu luoji da po le bianliang de invariant.
Kotlin mingque qufen zhe liang zhong qingkuang: check(...) hui diu chu “zhuangtai bu zhengque” de yichang.
Xiangxiang wo men shijian xiangmu de yi xiao duan (jia she jiao ta ExpenseTracker), li mian you “dangqian kaiqi de session” (li ru, dangqian huodong de yusuan yue). Ru guo daima xiang tianjia zhichu, dan huodong qijian hai mei xuan—zhe bu shi “yonghu dui addExpense(...) de can shu fuze”, er shi yingyong zhuangtai hai mei zhunbei hao.
class Session(var activeMonth: String?)
fun addExpense(session: Session, title: String) {
check(session.activeMonth != null) { "Active month is not selected" }
println("Added expense '$title' for month ${session.activeMonth}") // example
}
fun main() {
val s = Session(activeMonth = "2026-01")
addExpense(s, "Coffee") // Added expense 'Coffee' for month 2026-01
}
Ru guo activeMonth mei xuan, hai yao “jia zhuang yiqie zhengchang” ji xu zou shi hen weixian de. Zui hao shi li ke, qingchu di fail, rang kaifa zhe (ye jiu shi ni) zai ceshi/ diaoshi shi jiu kan dao wenti, er bu shi zai shangxian hou shou dao “anjing de cuowu baogao” (silent wrong report).
4. Keyi yujian de cuowu yu Ok/Error jieguo
You shi hou qingkuang hen taoyan, dan shi keyi yujian de: yonghu shuru le bu cunzai de mingling, xiang an id shanchu yi bi zhichu dan id bu cunzai, huo zhe cha xun yi ge muqian hai bu cunzai de leibie baogao.
Zhe bu xiang “shigu”. Zhe geng xiang “yingyong zhengchang de shenghuo fen zhi”: yonghu ke neng fan cuo, shuju ke neng que shi, zhe bu zhi de yong yichang kai yichang “yanhua xiuchang”.
Zai zhe zhong qingkuang, geng fangbian de shi ba jieguo zuo wei mingque de zhi fanhui, li ru:
sealed class CmdResult<out T> {
data class Ok<T>(val value: T) : CmdResult<T>()
data class Error(val message: String) : CmdResult<Nothing>()
}
Wei shenme zhe hen fangbian?
Yinwei diaoyong fang zai type shang jiu neng kan dao hetong: zhe ge han shu ke neng fanhui cuowu,ni bixu chuli. Zhe you dian xiang lu bian de jingtan “zhuan wan xiao xin”: ni keyi bu guan, dan chu shi le bie jingya.
Mini shili: “an id zhao zhichu”. Mei zhao dao—zhe bu shi shigu, er shi keyi yujian.
data class Expense(val id: Int, val title: String)
fun findExpense(expenses: List<Expense>, id: Int): CmdResult<Expense> {
val found = expenses.find { it.id == id }
?: return CmdResult.Error("Expense not found: id=$id")
return CmdResult.Ok(found)
}
fun main() {
val items = listOf(Expense(1, "Coffee"))
println(findExpense(items, 2)) // Error(message=Expense not found: id=2)
}
Zhe li de zhongyao guandian shi: “mei zhao dao” bu yi ding shi yichang, yinwei “mei you zhe ge yuan su” changchang shi yewu liucheng de yi bufen. Zai console/CLI yingyong li, ni tongchang hui ba Error bian cheng yonghu kan de dong de wenzi, ran hou jixu mingling xunhuan.
Wei shenme null bu shi wanyong de “cuowu”
Hen rongyi xiang zhe me zuo: “ru guo chule shenme wenti—wo jiu fanhui null”。Zhe hen you huoluo, yinwei hen kuai, ye bu yong sheng cheng xin type. Dan zhe ge fangshi you dai jia: null ji hu bu shuo ming renhe yuanyin.
null hen shihe “mei you zhi” huo “mei zhao dao” zhe zhong qingkuang, dang yuanyin bu zhongyao huo hen mingxian shi. Li ru, Map[key] fanhui V?,zhe hen zhengchang: “an key ke neng meiyou value”.
Dan zhi yao ni xuyao qufen bu tong yuanyin, null jiu kai shi dai lai fuzuo yong. Xiangxiang liang ge qingkuang:
- yonghu shuru le kong zi fu chuan
- yonghu shu ru le "12a"
Zhe liang zhong qingkuang, toIntOrNull() dou hui fanhui null。Dan dui yonghu (he ni diaoshi shi) lai shuo, liaojie chabie hen you yong.
“ruan hetong, bu shuo yuanyin” (you shi hou keyi):
fun parseAmountOrNull(text: String): Int? = text.toIntOrNull()
fun main() {
println(parseAmountOrNull("12a")) // null
}
“mingque cuowu + xiaoxi” (CLI li changchang geng hao):
fun parseAmount(text: String): CmdResult<Int> {
val trimmed = text.trim()
if (trimmed.isEmpty()) return CmdResult.Error("Amount is empty")
val n = trimmed.toIntOrNull() ?: return CmdResult.Error("Amount is not a number: '$text'")
if (n <= 0) return CmdResult.Error("Amount must be > 0, got $n")
return CmdResult.Ok(n)
}
Zhe li wo men bu yong yichang, yinwei zhe xie cuowu shi keyi yujian de: yonghu yong shou shuru, er shou you shi hou hui you ziji de xiangfa.
5. Zeren bianjie: yingyong de cengci
Xia mian shi yi ge hen zhongyao de jiagou dian, meiyou ta, “cuowu” zhe ge huati hen rongyi bian cheng “koutou pianhao zhi zheng”. Zai da xing xiangmu li, “yichang” he “cuowu zuowei zhi” de bianjie, changchang ganghao dui ying “ceng” de bianjie.
Zai wo men de kecheng li, wo men zao jiu zai xinsiang shang ba chengxu fen cheng ji ge bufen: CLI (shu ru/shu chu), domain (mingling luoji), storage (chucun). Zhe yang, cuowu xing shi de xuanze ye jiu hen ziran di he suo zai wei zhi gua gou.
Ba xia mian zhe zhang biao dang zuo “kaifa tuandui de yueding” lai kan (jiu suan tuandui zhi you ni he ni de mao):
| Ceng | Zuo shenme | Changjian wenti | Chang yong biaoda fangshi |
|---|---|---|---|
| CLI | du qu zi fu chuan, da yin hui fu | “yonghu shu ru le luan qi ba zao de dongxi” | cuowu zuowei zhi (Ok/Error), you shi hou ye yong null |
| Domain | yewu guize (mingling, jiancha) | “mei you zhe bi zhichu”, “bu neng shanchu zuihou yi ge yuan su” | cuowu zuowei zhi (Ok/Error), require/check yong yu nei bu baozheng |
| Storage | wenjian, DB, wangluo | “wenjian da bu kai”, “meiyou quanxian”, “geshi huai le” | changchang yong yichang, yinwei zhe shi I/O he huanjing guzhang |
Wei shenme storage changchang liu zai yichang? Yinwei “wenjian da bu kai” bu yi ding shi yewu luoji de keyi yujian fen zhi. Zhe shi huanjing de guzhang. Ni zong shi yao jueding zenme zuo (gaosu yonghu, jieshu chengxu, ti shi lu jing), dan zai di ceng daima li, zhi jie diu yichang, ran hou zai changjing bianjie tong yi chuli, geng jian dan ye geng “chengshi”.
Er zai domain ceng, fanhui Ok/Error changchang geng hao, yinwei zhe xie shi yingyong de “youxi guize”: yonghu keyi yao qiu shanchu yi ge bu cunzai de id—zhe shi keyi yujian de.
6. Shijian: mingling remove ji qi hetong
Wo men lai pin yi xiao duan, rang hetong “huo” qilai. Xiangxiang CLI ceng yi jing ba id (zuowei shu zi) parse hao le, ran hou wo men zai domain ceng zhixing shanchu zhichu.
Changjing: ru guo id mei zhao dao—zhe bu shi yichang,er shi Error。Ru guo list shi kong de, dan wo men yao shanchu—ye shi Error。Dan ru guo chuan jin lai de id shi fu shu, zhe geng xiang shi shang ceng daima de bug (CLI ying gai yi jing yanzheng), zhe li jiu ke yi yong require.
data class Expense(val id: Int, val title: String)
fun removeExpense(expenses: MutableList<Expense>, id: Int): CmdResult<Expense> {
require(id > 0) { "id must be > 0, got $id" }
val index = expenses.indexOfFirst { it.id == id }
if (index == -1) return CmdResult.Error("No expense with id=$id")
val removed = expenses.removeAt(index)
return CmdResult.Ok(removed)
}
fun main() {
val expenses = mutableListOf(Expense(1, "Coffee"))
println(removeExpense(expenses, 2)) // Error(message=No expense with id=2)
}
Zhe li zhongyao de shi shenme.
Bu hefa can shu (id <= 0) bei shi wei diaoyong hetong de weifan, yin ci yong require(...) zuo fail-fast. Er keyi yujian de “id mei zhao dao” ze fanhui Error,yinwei zhe shi zhengchang liucheng de fen zhi.
7. Ru he xuanze: shijian shang de pannan luoji
Zai shiji shang, juece zui fangbian de bu shi “wo xihuan yichang” huo “wo xihuan sealed class”, er shi wen zi ji ji ge hen luodi de wenti.
- Ru guo qingkuang keyi yujian bingqie jingchang fasheng (li ru, yonghu shu ru cuo le mingling), na me yichang jiu bian cheng zao yin. Ni hui bei po zai mei ge shiyong dian dou xie try/catch,daima hui yue lai yue xiang “Catch Me If You Can” de ju. Dui keyi yujian de fen zhi, jueda duoshu qingkuang xia “cuowu zuowei zhi” geng he shi.
- Ru guo chule wenti zhi hou ni hai neng jixu gongzuo (li ru, xianshi xiaoxi bing qing qiu chongxin shuru), na me “cuowu zuowei zhi” geng ziran: ni reng ran zai zhengchang de kongzhi liu zhong, zhi shi zou le ling yi tiao fen zhi.
- Ru guo qingkuang shi shigu/zhiming huo zhe biao shi chengxu luoji bei pohuai, na jiu bu neng mao ran jixu. Zhe shi hou yichang (huo require/check/error) shi heli de: ta bi po wo men bu neng jia zhuang yiqie an ran.
- Zuihou, ru guo ni zai yu “huanjing” de jiaojie chu (wenjian, wangluo, quanxian), na me yichang changchang geng “chengshi”: zhe shi huanjing guzhang, hen nan dang zuo yewu luoji de putong fen zhi. Zhe xie difang tongchang zai shang ceng changjing tong yi catch, ran hou bian cheng yonghu kan de dong de xiaoxi.
8. Liang ge jiduan, yi ji wei shenme ta men you hai
You liang ge jiduan, er qie xinshou hen chang jian.
Di yi ge jiduan—“shenme dou yong yichang”. Na me yonghu mei gui jie de dongzuo dou hui bian cheng try/catch cong lin. Dao mou ge shi hou, ni hui kai shi catch Exception (yinwei bu zhe yang jiu mei fa huo), ran hou ta bian cheng “wanyong dai”, li mian ji you zhen zheng de shigu, ye you keyi yujian de shuru cuowu. Zhe zhong daima de diaoshi tongchang xiang “kaogu”: ni zhao dao le stack trace, dan bu queding zhe dao di shi bug, hai shi yonghu an cuo le jian.
Di er ge jiduan—“wanquan bu yong yichang, quan bu fanhui Error(message)”. Zhe ye hen weixian: ni ke neng wuyi jian “sao dao ditan xia” yi zhong chengxu bu ying gai jixu de qingkuang (li ru, shuju invariant bei pohuai). Na me ni bu hui “chengshi de die”, er shi得到 “anjing de cuowu zhuangtai”, ran hou baogao hui cuo, shuju hui wai, yonghu kai shi huai yi ni de app li zhuo le poltergeist.
Chengshu de zuofa shi hunhe, dan yao yizhi: zai tong yi cengci xuan ding yi zhong celue, ran hou jianchi ta.
Jie xia lai hui shenme
Jin tian de jiangyi zhongdian shi yiyi he yueding. Wo men muqian you yi shi de zhi yong jian dan gongju: require/checkOk/Error.
Zai jie xia lai de jiangyi li, wo men hui xue hui geng you yishi di ba try/catch dang zuo expression (ji “cong try huo catch fanhui yi ge zhi”), bing kan dao geng biaozhun de “ba cuowu fengzhuang cheng zhi” de fangshi. Kotlin que shi zhichi try fanhui yi ge zhi de fengge, dang ni xuanze “chu cuowu jiu fanhui default huo xiaoxi” zhe zhong celue shi hui hen fangbian.
Jichu reng ran yi yang: xian jueding shenme suan cuowu he ta dui diaoyong fang ying gai chang shenme yang,ran hou zai xuanze yong shenme yufa.
9. Changjian cuowu
Cuowu #1: ba keyi yujian de qingkuang bian cheng yichang.
Ru guo yonghu shu ru le yi ge weizhi mingling, zhe bu shi “chengxu huai le”, er shi “yonghu yao qiu le yi ge bu cunzai de dongxi”. Dang ni yong yichang lai biaoda zhe xie qingkuang, daima hen kuai jiu hui bei try/catchOk/Error fanhui, ran hou yong putong de when chuli.
Cuowu #2: ba null dang zuo wanyong cuowu.
null hen shan chang biaoda “mei you zhi”, dan ji hu bu biaoda “wei shenme”. Jieguo ni bu de bu yao me zi ji nao bu bu quan, yao me da yin yi ge hen mohu de “shibai le”. Ru guo yuanyin dui yonghu hen zhongyao (zai CLI li ji hu zong shi hen zhongyao), na jiu bi qi fanhui null,geng hao shi fanhui Error("clear message").
Cuowu #3: require/check yong cuo yiyi.
You shi hou xinshou hui xie require(false) zhi shi “wei le rang ta die”. Cong yufa shang kan mei wenti, dan yiyi jiu diu le. require ying gai biaoda can shu de qianzhi tiaojian, er check ying gai biaoda zhuangtai invariant. Zhe yang daima jiu hui “zi wo shuo ming”: zhi kan yi hang, jiu zhidao shui dui zhengque xing fuze (diaoyong fang, hai shi nei bu luoji).
Cuowu #4: “xiao yin” cuowu, jia zhuang yiqie zhengchang.
Zui yin xian de cuowu shi: chengxu zai chule wenti zhi hou hai jixu gongzuo, dan shi qi shi yi jing bu ying gai jixu. Li ru, shanchu bu cunzai de id ni “mian sheng” hu lue, yonghu yiwei shanchu chenggong le. Geng zhengque de zuofa shi fanhui Error bing dai shang xiaoxi, huo zhe zai wufa jixu de changjing zhijie zhongzhi liucheng.
Cuowu #5: zai tong yi ge han shu li hun yong duozhong hetong.
Dang tong yi ge han shu you shi diu yichang, you shi fanhui Error,you shi fanhui null,diaoyong fang jiu hui bian cheng zhentan: “zhe ci wo gai jiancha shenme?”. Jin liang rang han shu zhi you yi ge qingchu de hetong: yao me yong zhi lai biaoda wenti (Ok/Error),yao me yong yichang fail (qie yiyi shang you chongfen liyou),yao me zai yange xian ding de qingkuang xia fanhui T?(zhi xian “mei zhao dao” huo “mei you zhi” zhe lei).
GO TO FULL VERSION