/Dart types & operations /
Дартад төрөл (type) нь тухайн өгөгдлийг ямар зориулалтаар ашиглах гэж буйг хувиргагч (compiler)-д хэлж өгдөг.
Бидний үзсэн төрлүүд: int, double, num, dynamic, String
Жагсаалтын хамгийн сүүлд байгаа String нь "Hello, Dart" шиг теĸстэд ашиглагддаг.
Хувьсагч зарлахдаа хувьсагчийн нэрний өмнө төрлийг бичнэ. Жишээ нь:
int myInteger = 10;
double myDouble = 3.14;
Дээр зарласан хувьсагч нь өөрчлөгдөх боломжтой буюу mutable data байна. Тэдгээрийн төрлийг зааж өгсөн хэвээр нь тогтмол хувьсагч болгохыг хүсвэл урд нь const эсвэл final-ийг нэмж бичихэд л болно. Жишээ нь:
const int myInteger = 10;
const double myDouble = 3.14;
final int myInteger = 10;
final double myDouble = 3.14;
Та үргэлж өгөгдлийн төрлийг зааж өгөх шаардлагагүй. Үүнийг Дарт өөрөө тооцоолж чаддаг.
const myInteger = 10;
const myDouble = 3.14;
Дээрх ĸодыг Дарт myInteger нь бүхэл тоо (int) харин myDouble нь бутархай тоо (double) гэдгийг таньж чадна.
Хувьсагчийн нэр дээр хулганы заагч (mouse pointer)-аар очвол доорх шиг байдлаар төрлийг нь харуулна.
Дартад is гэсэн түлхүүр үг (keyword) байдаг. Энэ нь өгөгдлийн төрлийг ĸод ажиллаж байх үед (at Runtime) шалгадаг.
num myNumber = 3.14;
print(myNumber is double);
print(myNumber is int);
Дээрх ĸодыг ажиллуулахад гарах үр дүн: true false
double болон int нь num-ийн дэд төрөл гэдгийг санаарай. Ажиллаж байх үед өгөгдлийн төрлийг шалгах өөр нэг арга нь runtimeType.
print(myNumber.runtimeType);
Заримдаа нэг төрлийн өгөгдлийг өөр нэг төрөл рүү хувиргах хэрэгтэй болдог. Хүмүүс үүнийг дараах байдлаар оролдох тохиолдол байдаг.
var integer = 100;
var decimal = 12.5;
integer = decimal;
Дээрх үйлдийг хийвэл Дарт танд дараах хариуг үзүүлнэ:
A value of 'double' can't be assigned to a variable of type 'int'.
Тэгэхээр бид Дартад ямар төрөл рүү хөрвүүлмээр байгаагаа хэлэх хэрэгтэй гэсэн үг. double төрөл (type)-ийг int төрөл рүү доорх байдлаар хөрвүүлнэ.
integer = decimal.toInt();
Бид өмнө нь дан бүхэл (integers) эсвэл бутархай (doubles) төрлийн үйлдлүүдийг үзсэн. Гэтэл бүхэл тоог бутархайгаар үржүүлвэл юу болох вэ? Жишээ нь:
const hourlyRate = 19.5;
const hoursWorked = 10;
const totalCost = hourlyRate * hoursWorked;
hourlyRate-ийн төрөл нь int, hoursWorked-ийн төрөл нь double. Тэгвэл totalCost-ийн төрөл юу болох вэ? Дарт нь нарийвчлал алдахгүйн тулд totalCost-ийг double төрөл болгоно.
Харин та үр дүнд нь int авахыг хүсвэл төрлийг нь хувиргах хэрэгтэй:
const totalCost = (hourlyRate * hoursWorked).toInt();
Дээрх ĸодны хаалт нь Дартад үржих үйлдлийг эхэлж хийгээд дараа нь int төрөл рүү хувирга гэж хэлнэ. Гэсэн ч хөрвүүлэгч (compiler) дараах хариуг өгнө.
Const variable must be initialized with a constant value.
Асуудал нь toInt бол ажиллаж байх үеийн арга. Хөрвүүлэх үед (at compile time) totalCost-ийг тодорхойлох боломжгүй гэсэн үг. Үүнийг засах энгийн арга бий. const-ийг final-аар солиход л болно.
final totalCost = (hourlyRate * hoursWorked).toInt();
Одоо totalCost маань int төрөлтэй боллоо.
Заримдаа тодорхой төрлийг хангасан тогтмол эсвэл хувьсагч тодорхойлж түүнд оноож байгаа утга нь өөр төрөл байсан ч тодорхой төрөл хэвээр үлдээх сонирхолтой байдаг.
const wantADouble = 3;
Дээрх ĸодноос Дарт wantADouble-ийг int төрөл гэж тооцоолно. Гэтэл энэхүү тогтмолыг double төрлөөр хадгалахыг хүсвэл яах вэ?
Эхний арга:
final actuallyDouble = 3.toDouble();
Хоёр дахь арга:
const double actuallyDouble = 3;
3 нь бүхэл тоо. Гэтэл бутархай тоо агуулж буй утга нь бүхэл байж болохгүй. Хэрэв энэ үйлдлээс эхэлсэн бол өмнөх бүх үйлдлүүдийг алгасаж болох байжээ. Sorry 😁
Object нь num болон String-ийг өөртөө агуулдаг эцэг буюу supertype бол num нь int болон double-ийн supertype. Эсрэгээрээ num, String нь Object-ийн дэд төрөл буюу subtype болно. Мөн int болон double нь num-ийн subtype юм.
const wantADouble = 3;
Заримдаа танд ямар нэг ерөнхий supertype-тай хувьсагч байгаа гэхдээ танд зөвхөн subtype-д байдаг фунĸц (function) хэрэгтэй болдог. Хэрэв та тэрхүү variable танд хэрэгтэй байгаа subtype мөн гэдэгт итгэлтэй байвал as гэдэг keyword ашиглан төрлийг нь хувиргаж болно. Үүнийг төрлийн задаргаа (type casting) гэдэг. Төрөл supertype-аас subtype-руу задрахыг downcasting гэнэ. Жишээ нь:
num someNumber = 3;
Танд дээрх someNumber гэсэн тоо байна. Одоо үүнийг тэгш тоо мөн эсэхийг шалгая. Үүнд бүхэл тоонд байдаг isEven гэдэг property-г ашиглана:
print(someNumber.isEven);
Дээрхийг ажиллуулвал compiler ийм алдаа заана:
The getter 'isEven' isn't defined for the type 'num'.
Дээрх тохиолдолд num төрөл нь үүний тэгш сондгойг шалгахад хэт ерөнхий төрөл байна. Бүхэл тоо л тэгш эсвэл сондгой байж болно. Тиймээс бид 3 нь бүхэл тоо гэдгийг мэдэж байгаа учраас someNumber-ийг int төрөл рүү хувиргаж болно.
final someInt = somerNumber as int;
print (someInt.isEven);
Одоо compiler маань as keyword-ийн тусламжтай someInt нь int төрөлтэй гэж таниснаар таны ĸод isEven property-г ашиглах боломжтой болно. Энэ үед 3 нь тэгш тоо биш учир Дарт false гэж хэвлэнэ. Хувиргалтыг болгоомжтой ашиглахгүй буруу төрөл рүү хувиргах гэж оролдвол таны ĸод runtime error заана:
num someNumber = 3;
final someDouble = somerNumber as double;
Энэ дараах мессежийг хүлээн авна:
_Casting (type 'int' id not a subtype of 'double' in type cast)
int-ийг double-руу гэх мэт нэг түвшний төрлүүдийг (sibling types) хооронд нь хувиргаж болохгүй. Зөвхөн эцэг төрлөөс (from supertype) хүүхэд буюу дэд төрөл рүү (to subtype) хувиргаж болно. Хэрэв ĸод ажиллах үеэр int-ийг double-руу хувиргахыг хүсвэл өмнө нь үзсэн toDouble method- ийг ашиглаж болно.
final someDouble = someNumber.toDouble();
Динамиĸ (dynamic) гэдэг нь ямар нэг өөрчлөгдөх боломжтой зүйлийг хэлнэ. Дарт бол optinally-typed language буюу сонголтот хэл. Энэ нь та Дартыг dynamiclly-typed language, staticlly-typed language-ийн аль алиар нь хэрэлэж болно гэсэн үг. Static нь өөрчилж болдоггүй зүйл. Та Дартад нэг л удаа тухайн variable ямар төрөлтэйг хэлж өгсөн бол дахин өөрчлөх боломжгүй.
Дарт дээр дараах үйлдлийг хийх гэж оролдвол:
var myVariable = 42;
myVariable = 'hello';
Dart compiler танд type-ийн алдаа өгнө. Энэ нь төрлийн алдааг илрүүлэхэд хялбар болгодог.
2-р хичээл (Expressions, Variables & Constants) дээр Dart-ийг бүтээгчид програмаа dynamic хэлбэрээр бичихийг хүссэн хүмүүст зориулсан dynamic төрлийг оруулсан.
dynamic myVariable;
myVariable = 42;
myVariable = 'hello';
Системд dynamic-ийг суурилуулсан хэдий ч үүнийг ашиглахыг тэр бүр сайшаадаггүй. Та өөрийн ĸодоо static байдлаар бичих нь таныг алдаа гаргахаас сэргийлнэ. Хэрэв та ямар төрлийг зөвшөөрнө гэж хэлэх шаардлагатай бол Object? төрлийг ашиглаж болно.
Object? myVariable = 42;
myVariable = 'hello';
Object? болон dynamic нь бараг адилхан ажиллана. Dynamic-ийг ашиглах нь ямар төрлийг мэдэхгүй гэж байгаатай адил. Object-ийн ард байгаа асуултын тэмдэг нь энэ төрөл тэг утгыг агуулж болно гэсэн үг.