Một string
về cơ bản là một chuỗi các char
giá trị (trong Haskell, BTW, String
là một loại bí danh cho [Char]
). Một câu hỏi chung hơn, sau đó, sẽ là nếu nó có thể tĩnh khai báo một danh sách như có một kích thước nhất định.
Tính năng ngôn ngữ như vậy được biết là Dependent Types và F # không có. Câu trả lời ngắn, do đó, là điều này là không thể làm trong một thời trang khai báo.
Cách dễ dàng nhất, và có lẽ cũng thành ngữ nhất, bằng cách nào, sau đó, sẽ được xác định Code
dưới dạng đĩa đơn hợp kỳ thị Union:
type Code = Code of string
Trong module định nghĩa Code
, bạn cũng muốn xác định một chức năng mà khách hàng có thể sử dụng để tạo ra giá trị Code
:
let tryCreateCode candidate =
if System.String.IsNullOrWhiteSpace candidate
then None
else Some (Code candidate)
chức năng này chứa logic thời gian chạy có thể ngăn chặn khách hàng từ việc tạo ra sản phẩm nào Code
giá trị:
> tryCreateCode "foo";;
val it : Code option = Some (Code "foo")
> tryCreateCode "";;
val it : Code option = None
> tryCreateCode " ";;
val it : Code option = None
Điều gì ngăn cản khách hàng tạo giá trị Code
không hợp lệ? Ví dụ: không phải khách hàng có thể phá vỡ chức năng tryCreateCode
và chỉ cần viết Code ""
?
Đây là nơi có signature files.Bạn có thể tạo một tập tin chữ ký (.fsi
), và trong đó khai báo các loại và chức năng như thế này:
type Code
val tryCreateCode : string -> Code option
Ở đây, loại Code
được khai báo, nhưng 'constructor' của nó không phải là. Điều này có nghĩa là bạn không thể tạo trực tiếp các giá trị của loại này. Này, ví dụ, không biên dịch:
Code ""
Các lỗi được đưa ra là:
lỗi FS0039: Giá trị, xây dựng, không gian tên hoặc gõ 'Mã' không được định nghĩa
Cách duy nhất để tạo giá trị Code
là sử dụng chức năng tryCreateCode
.
Như đưa ra ở đây, bạn không còn có thể truy cập vào các chuỗi giá trị cơ bản của Code
, trừ khi bạn cũng cung cấp một chức năng cho rằng:
let toString (Code x) = x
và khai báo nó trong cùng một tập tin .fsi
như trên:
val toString : Code -> string
Điều đó có thể trông giống như rất nhiều công việc, nhưng thực sự chỉ có sáu dòng mã và ba dòng khai báo kiểu (trong tệp .fsi
).
Hãy xem bài đăng này: http://fsharpforfunandprofit.com/posts/designing-with-types-more-semantic-types/ - phần "Lập mô hình chuỗi bị ràng buộc với các loại". Bạn có thể sẽ cần phải làm điều gì đó như thế này – Petr
@Petr Tôi thấy bài đăng này nhưng tôi thấy giải pháp này hơi phức tạp. Cảm ơn bạn đã liên kết. – Mikhail
Có, tôi đồng ý rằng bài đăng đó hơi phức tạp một chút. Tôi có một số ví dụ tốt hơn ở đây: https://gist.github.com/swlaschin/54cfff886669ccab895a. Như những người khác đã chỉ ra, các giải pháp không đặc biệt thanh lịch. OTOH, bạn cũng phải làm điều tương tự trong mã OO. – Grundoon