2011-12-24 87 views
22

tôi đang học D và đã thấy rất nhiều mã như thế này:Toán tử chấm than?

ushort x = to!ushort(args[1]); 

Tôi giả định này phôi args[1] để ushort, nhưng sự khác biệt giữa điều này và cast(ushort) là gì?

CHỈNH SỬA: Và toán tử dấu chấm than nào có sử dụng khác?

Trả lời

31

Trong D,

to!ushort(args[1]) 

là viết tắt cho các mẫu instantiation

to!(ushort)(args[1]) 

và cũng tương tự như

to<ushort>(args[1]) 

bằng các ngôn ngữ như C++/Java/C#.

Dấu chấm than là lưu ý thực tế rằng đó không phải là đối số thông thường, mà là đối số mẫu.

Ký hiệu không không ngoặc sử dụng góc vì đó là những ridiculously khó để phân tích một cách chính xác cho một trình biên dịch (họ làm cho ngữ pháp rất context-sensitive), mà làm cho nó có nhiều khó khăn hơn để thực hiện một trình biên dịch chính xác. Xem here để biết thêm thông tin.

Cách sử dụng duy nhất khác mà tôi biết chỉ là hoạt động 'không' đơn nhất (ví dụ: false == !true) ... Tôi không thể nghĩ ra bất kỳ cách sử dụng nào khác vào lúc này.


Về các diễn viên:

cast(ushort) là một kiểm soát dàn diễn viên, vì vậy nó sẽ không ném một ngoại lệ nếu giá trị là ra khỏi phạm vi.

to!ushort()được chọn truyền, vì vậy, nó sẽ ném ngoại lệ nếu giá trị nằm ngoài phạm vi.

+0

cảm ơn rất nhiều =] câu trả lời tuyệt vời! – thwd

+3

Dường như cũng vậy! là nhiều hơn của một diễn viên từ vựng, ví dụ! string (f) là hợp lệ cho điểm nổi f và cast (string) f - not. –

+5

Tôi sẽ chỉ ra rằng kỹ thuật nói 'to! Ushort (val)' không thực sự là một diễn viên. Đó là một chuyển đổi sử dụng hàm 'std.conv.to'. Nó đã được kiểm tra, nhưng nếu bạn bắt đầu gọi nó là một diễn viên, bạn có nguy cơ gây nhầm lẫn. Việc đúc chỉ được thực hiện với toán tử truyền. –

3

Dấu chấm than ở đây không phải là toán tử, nó chỉ là một phần mã thông báo của cú pháp khởi tạo khuôn mẫu rõ ràng (được mô tả chi tiết here).

std.conv.to (docs) là mẫu chức năng để chuyển đổi giữa các loại tùy ý. Nó được thực hiện hoàn toàn trong thư viện và không có hỗ trợ đặc biệt trong ngôn ngữ. Nó có phạm vi rộng hơn và khác so với toán tử truyền.

Mẫu to lấy hai tham số loại; loại "đến" và loại "từ", theo thứ tự đó. Trong ví dụ của bạn, mẫu được khởi tạo rõ ràng với đối số loại đơn ushort cho tham số "đến" và đối số loại thứ hai string (giả sử args xuất phát từ tham số đầu tiên đến main) được tự động suy ra từ đối số hàm thông thường được chuyển đến hàm (args[1]) làm tham số "từ".

Hàm kết quả nhận tham số chuỗi và trả về phân tích cú pháp phân tích từ chuỗi đó hoặc ném một ngoại lệ nếu nó không thành công. Toán tử truyền sẽ không thử loại chuyển đổi cấp cao này.

Lưu ý rằng nếu có nhiều hơn một tham số mẫu rõ ràng, hoặc tham số đó có nhiều hơn một thẻ trong nó (ushort là một thẻ từ khóa duy nhất), bạn phải quấn mẫu danh sách tham số trong ngoặc đơn:

ushort result; 
result = to!(typeof(result))(args[1]); 

Trong ví dụ này, typeof, (, result) là bốn mã thông báo riêng biệt và do đó cần có dấu ngoặc đơn.

Để trả lời câu hỏi cuối cùng của bạn, ! thẻ cũng được sử dụng cho các nhà điều hành unary không, không liên quan đến mẫu instantiations:

bool yes = true; 
bool no = !yes; // 'no' is false 
2

Bạn đã có hai câu trả lời tuyệt vời bởi jA_cOp và Merhdad. Tôi chỉ muốn trả lời trực tiếp cho câu hỏi OP (sự khác biệt giữa điều này và diễn viên (ushort) là gì?) - Sự khác biệt là cast(ushort)args[1] sẽ không hoạt động (bạn không thể truyền từ chuỗi đến một uint giống như vậy), trong khi to!(type)(param) mẫu biết phải làm gì với chuỗi và cách chuyển đổi nó thành kiểu nguyên thủy.

+0

cảm ơn rất nhiều, điều này có ý nghĩa. – thwd

Các vấn đề liên quan