Write never returning func with Never (in Burmese)
Prerequisite
- Basic knowledge of Swift syntax
- Error handling in general
What I’ll cover
- Never ဆိုတာဘာလဲ
- Never နဲ့ Void ဘာကွာလဲ
- ‘Never’ usage across Swift standard library
- နိဂုံး
What is Never
ဒီတစ်ခေါက်မှာတော့ Swift မှာ လူသိနည်းပေမယ့် မသိလိုက်ပဲ သုံးဖြစ်နေတဲ့ Never type အကြောင်းကို ပြောပြပေးချင်ပါတယ်။ Never ဆိုတာ caseless enum type တစ်ခုဖြစ်ပါတယ်။ Never ဟာ ဘာ value ကိုမှ return မပြန်တဲ့ type တစ်ခုလို့ပြောလို့ရပါတယ်။
The return type of functions that do not return normally, that is, a type with no values.
Never ကို func တွေရဲ့ return type အနေနဲ့ အသုံးပြုလို့ရပါတယ်။ ဘယ်လို func မျိုးလည်းဆိုတော့ error တက်သွားပြီး အဲ့ error ကလည်း ဘယ်လိုမှ handle လို့မရပဲ app ကို terminate လုပ်ကိုလုပ်ရမယ့်အခါမှာ ဒါမှမဟုတ် func က ဘယ်တော့မှ terminate မဖြစ်ပဲ app lifespan တစ်လျှောက် run နေမယ့် အခြေအနေမျိုးမှာ အဲ့ func ရဲ့ တစ်ကယ့် return value ကို return ပြန်စရာမလိုဘဲ Never ကို return value အနေနဲ့ အသုံးပြုနိုင်ပါတယ်။ အခု ဒီဟာကိုနားမလည်သေးရင် အောက်က code example တွေနဲ့ ရှင်းပြတာကိုဖတ်ပြီးမှ တစ်ခေါက်လာပြန်ဖတ်ပါ။
Never Vs Void
ရှေ့မှာ Never ဆိုတာ ဘာ value မှ return မပြန်တဲဲ့ return type ဖြစ်တယ်လို့ ပြောခဲ့ပါတယ်။ အဲ့တော့ ဒီနေရာမှာ မေးစရာရှိတာက Void နဲ့ဘာကွာလဲ ဘာ value မှ return မပြန်တာချင်းအတူတူ ဘာကြောင့် Void ကိုမသုံးရတာလည်း စသဖြင့် စဉ်းစားစရာအချက်တွေ ထွက်လာပါတယ်။ အရင်ဆုံး ဒီမေးခွန်းကိုမဖြေခင် Void ဆိုတာဘာလည်း အရင်လေ့လာကြည့်ပါမယ်။
Void ဆိုတာ တစ်ကယ်တော့ ‘()’ tuple တစ်ခုဖြစ်ပြီး ဘာ element မှမရှိတဲ့ empty tuple တစ်ခု ဖြစ်ပါတယ်။ ဒါကြောင့် ‘Void’ ကို ‘()’ လို့လည်း ရေးလို့ရပါတယ်။
Void က ဘာ value မှ return မပြန်ဘူးလို့ အလွယ်ပြောလို့ရပေမယ့် တစ်ကယ့်တစ်ကယ်တော့ tuple type ကို return ပြန်နေပါတယ်။ ‘Never’ နဲ့ ‘Void’ ကွာခြားချက်ကိုသိရဖို့ code အချို့ ရေးကြည့်ပါမယ်။
App ကို terminate ဖြစ်သွားအောင်လုပ်နိုင်တဲ့ custom function တစ်ခုရေးလိုက်ပါတယ်။ ဒီနေရာမှာ သူ့ရဲ့ return type ကို ဘာမှမရေးထားတဲ့အတွက် default Void ဖြစ်နေပါလိမ့်မယ်။ (Good practise အရတော့ ဘယ်တော့မှ ‘exit(0)’ ကို မသုံးသင့်ပါဘူး။ For more info, read here.)
- ‘String’ type ကို return ပြန်တဲ့ ‘doSomeSeriousWork’ ဆိုတဲ့ func တစ်ခုရေးထားပါတယ်။
- လိုအပ်တဲ့ condition အချို့ကို စစ်ဆေးပါတယ်။
- တစ်ကယ်လို့ လိုအပ်တဲ့ precondition satisfy မဖြစ်ခဲ့ရင် ရှေ့မှာရေးထားတဲ့ ‘crashAppSeriously()’ ဆိုတာကို ခေါ်ပေးလိုက်ပါတယ်။
- Condition check တွေအားလုံး အဆင်ပြေတယ်ဆိုရင်တော့ လိုအပ်တဲ့ code တွေကို execute လုပ်ပြီး နောက်ဆုံးမှာ string value တစ်ခု return ပြန်ပေးလိုက်ပါတယ်။
အပေါ်က code ကို build လိုက်ရင် “Missing return in global function expected to return ‘String’” ဆိုပြီး error တက်ပါလိမ့်မယ်။ ဘာကြောင့်လဲဆိုတော့ ‘String’ return ပြန်ရမယ့် func မှာ Void return ပြန်ထားတဲ့အတွက် ဖြစ်ပါတယ်။
Compilation error ပျောက်သွားချင်ရင် empty string တစ်ခု return ပြန်ပေးလိုက်ပါတယ်။ ဒါပေမယ့် ပြန်စဉ်းစားကြည့်ရင် crashAppSeriously ဆိုတဲ့ func က ဘယ်လိုမှ handle လုပ်လို့မရဘဲ app terminate လုပ်ကိုလုပ်ရမယ့် အခြေအနေမျိုးအတွက် သုံးတာပါ။ တစ်ခါ ‘exit(0)’ ကို execute လုပ်တာနဲ့တစ်ပြိုင်နက် program exit သွားမှာဖြစ်တဲ့အတွက် compile error ပျောက်သွားအောင်ရေးထားတဲ့ return “” ဆိုတာသည် ဘယ်တော့မှ execute လုပ်မှာမဟုတ်တဲ့ unreachable code ဖြစ်ပါတယ်။ ဒီတစ်ခါ return type ကို Never လို့ ပေးကြည့်ပါမယ်။
ဒီလို Never return ပြန်လိုက်တာနဲ့တစ်ပြိုင်နက် compiler ကနေပြီး ဒီ Never return ပြန်ထားတဲ့ func ခေါ်ပြီးတာနဲ့တစ်ပြိုင်နက် program terminate ဖြစ်သွားမယ်ဆိုတာကို သိသွားပြီး ဘာ type checking မှဆက်မလုပ်တော့ပါဘူး။ ဆိုလိုတာက ဒီ if block ထဲရောက်လာတာနဲ့တစ်ပြိုင်နက် program က ရပ်သွားမှာဖြစ်တဲ့အတွက် ဒီ func က ဘာ return ပြန်တယ် မပြန်ဘူးဆိုတာ အရေးမကြီးတော့ပါဘူး။
ပြန် build ကြည့်ရင် error ပျောက်သွားပါလိမ့်မယ်။ ဒီလောက်ဆို ‘Never’ နဲ့ ‘Void’ ရဲ့ ကွာခြားချက်ကို သိပြီလို့ထင်ပါတယ်။
Never usage across Swift standard library
ကျွန်တော် အပေါ်မှာရေးထားတဲ့ exit(_:) သည်ပင်လျှင် Never ကို return ပြန်ထားပါတယ်။ အခြား never return ပြန်တဲ့ func အချို့ရှိပါသေးတယ်။
Example code တွေရေးပြတဲ့အခါ အများဆုံးသုံးဖြစ်တာကတော့ fatalError(_:file:line:) ပါ။
Never type ကို generic parameter အနေနဲ့လည်း အသုံးပြုလို့ရပါတယ်။
ဉပမာ Combine framework ရဲ့ Failure type ကို Never ပေးလိုက်ရင် sink လုပ်တဲ့အခါ completion မှာ failure case ကို ignore လုပ်လို့ရတာကို တွေ့ရပါလိမ့်မယ်။
နိဂုံး
Never type အကြောင်းနဲ့ ဘာကြောင့်သုံးရသလဲ Never ကိုမသုံးပဲရော ရေးလို့ရမလား စတာတွေကို လေ့လာခဲ့ပြီးပါပြီ။ Never type ကိုသုံးခြင်းကြောင့် compile time checking ကို bypass လို့ရပြီး မလိုအပ်တဲ့ unreachable code တွေကို ရေးစရာမလိုအောင် ကူညီပေးပါတယ် (’crashAppSeriously’ မှာ သုံးသွားတဲ့ပုံစံကို ကြည့်ပါ)။ Application developer တစ်ယောက်အနေနဲ့ Never သုံးရမယ့် scenario မရှိသလောက်နည်းပေမယ့် library/framework တွေ ရေးမယ်ဆိုရင်တော့ လိုကောင်းလိုလာနိုင်တဲ့အတွက် သိထားသင့်တယ်လို့ ယူဆပါတယ်။