«نوع مات» در Gleam نوعی سفارشی است که فقط ماژولی که آن نوع را تعریف میکند میتواند مقدارهایی از آن نوع را بسازد یا با آنها تطبیق الگو کند. این ویژگی برای ساختن نوعهایی مفید است که باید فقط به روشی خاص استفاده شوند.
نوع مات با کلیدواژهی opaque تعریف میشود.
pub opaque type PositiveInt {
PositiveInt(inner: Int)
}
این نوع PositiveInt برای موقعیتهایی است که در آنها یک عدد صحیح لازم است، اما آن عدد باید صفر یا بزرگتر باشد. نمیتوان از Int معمولیِ Gleam استفاده کرد، چون آنها هم میتوانند منفی باشند.
ماژولی که این نوع را تعریف میکند میتواند تابعی برای گرفتن مقدار عدد صحیح درونی تعریف کند و همچنین تابعی برای ساختن نوع PositiveInt که اگر مقدار مثبت نباشد، خطا برمیگرداند.
pub fn from_int(i: Int) -> Result(PositiveInt, String) {
case i {
_ if i < 0 -> Error("Value must be positive")
_ -> Ok(PositiveInt(i))
}
}
pub fn to_int(i: PositiveInt) -> Int {
i.inner
}
با این API، ماژولهای دیگر نمیتوانند یک PositiveInt با مقدار منفی را بسازند، بنابراین هر تابعی که یک PositiveInt میگیرد میتواند مطمئن باشد که مقدارش مثبت است.
دانشآموزان تیزبین متوجه شدهاند که نوع TreasureChest در تمرین قبلی چندان امن نبود!
اگر از تابع get_treasure استفاده میکردید، باید رمز عبور را وارد میکردید، اما همچنان میتوانستید نوع TreasureChest را ساختارشکنی کنید و بدون دانستن رمز عبور به گنج برسید.
بیایید با استفاده از یک «نوع کدر» این مشکل را برطرف کنیم.
TreasureChest را تعریف کنیدنوع TreasureChest دو فیلد دارد:
String است.نوع TreasureChest باید کدر باشد.
create را تعریف کنیداین تابع دو آرگومان میگیرد:
String.تابع یک TreasureChest برمیگرداند که رمز عبور و آن مقدار را در خود دارد.
اگر رمز عبور کوتاهتر از ۸ کاراکتر باشد، تابع باید خطایی برگرداند با این پیام که Password must be at least 8 characters long.
open را تعریف کنیداین تابع دو آرگومان میگیرد:
TreasureChest.String.اگر رمز عبور با رمز عبور موجود در TreasureChest یکسان باشد، تابع باید گنج را برگرداند؛ در غیر این صورت، باید خطایی برگرداند با این پیام که Incorrect password.