2012-07-19 15 views
11

Tôi muốn một hàm nhận loại giá trị khi chạy. Ví dụ sử dụng:Làm cách nào để nhận loại giá trị trong Đề án?

(get-type a) 

nơi adefine d là giá trị Đề án tùy ý.

Làm cách nào để thực hiện việc này? Hoặc tôi có phải tự mình thực hiện điều này, sử dụng ngăn xếp của boolean?, number?, v.v. không?

Trả lời

11

Trong triển khai Đề án với hệ thống đối tượng giống như Tiny-CLOS, bạn chỉ có thể sử dụng class-of. Dưới đây là một phiên mẫu trong Racket, sử dụng Swindle:

$ racket -I swindle 
Welcome to Racket v5.2.1. 
-> (class-of 42) 
#<primitive-class:exact-integer> 
-> (class-of #t) 
#<primitive-class:boolean> 
-> (class-of 'foo) 
#<primitive-class:symbol> 
-> (class-of "bar") 
#<primitive-class:immutable-string> 

Và tương tự với GOOPS Guile sử dụng:

[email protected](guile-user)> ,use (oop goops) 
[email protected](guile-user)> (class-of 42) 
$1 = #<<class> <integer> 14d6a50> 
[email protected](guile-user)> (class-of #t) 
$2 = #<<class> <boolean> 14c0000> 
[email protected](guile-user)> (class-of 'foo) 
$3 = #<<class> <symbol> 14d3a50> 
[email protected](guile-user)> (class-of "bar") 
$4 = #<<class> <string> 14d3b40> 
4

Để kiểm tra loại một cái gì đó chỉ cần thêm một dấu hỏi sau khi loại, ví dụ để kiểm tra nếu x là một số:

(define get-Type 
    (lambda (x) 
    (cond ((number? x) "Number") 
      ((pair? x) "Pair") 
      ((string? x) "String") 
      ((list? x) "List")))) 

Chỉ cần tiếp tục với điều đó.

+6

OP được hỏi cụ thể nếu có cách thay thế cho phương pháp này. Ngoài ra, tại sao sử dụng lồng nhau 'if's khi bạn có thể sử dụng' cond'? \ * boggles \ * –

+0

@ewein @Chris Jester-Young là điều này bị thiếu? Đối với '(get-Type (ô tô (string-> list (number-> string 5))))' điều này không trả về bất cứ điều gì. – ArtB

+1

Hóa ra trường hợp của tôi, bit bị thiếu là 'ký tự? '. Vì lợi ích đầy đủ, cũng có 'vector?'. – ArtB

9

Trong vợt, bạn có thể sử dụng gói describe bởi Doug Williams từ hành tinh. Nó hoạt động như thế này:

> (require (planet williams/describe/describe)) 
> (variant (λ (x) x)) 
'procedure 
> (describe #\a) 
#\a is the character whose code-point number is 97(#x61) and 
general category is ’ll (letter, lowercase) 
+0

Gói này thực sự hữu ích. Tôi ước nó là một phần của Racket cốt lõi. – Salil

3

Tất cả câu trả lời ở đây đều hữu ích, nhưng tôi nghĩ rằng mọi người đã bỏ qua giải thích tại sao điều này khó; tiêu chuẩn Đề án không bao gồm một hệ thống kiểu tĩnh, vì vậy các giá trị không thể được cho là chỉ có một "loại". Mọi thứ trở nên thú vị trong và xung quanh các kiểu con (ví dụ: số vs dấu chấm động) và kiểu kết hợp (loại nào bạn cung cấp cho một hàm trả về một số hoặc một chuỗi?).

Nếu bạn mô tả việc sử dụng mong muốn của mình nhiều hơn một chút, bạn có thể khám phá ra rằng có nhiều câu trả lời cụ thể hơn sẽ giúp bạn nhiều hơn.

+5

Ông nói "lúc chạy", vì vậy điều này không có gì để làm với các loại tĩnh. Đó là các loại giá trị động (thời gian chạy) của anh ta sau – newacct

+0

Bạn đang thiếu điểm của John, theo nghĩa là các loại thời gian chạy động không phải lúc nào cũng có đủ thông tin để phân biệt. Ví dụ cụ thể: giả sử rằng tôi có một chương trình đề cập đến màu sắc và tên. Tôi có thể chọn để đại diện cho các giá trị của các loại này chỉ với chuỗi. Sau đó, nếu tôi thấy từ "Xám", tôi không có đủ thông tin để phân biệt loại vì tôi đang sử dụng cùng một biểu diễn. – dyoo

+0

Ditto; bạn có thể xóa từ "tĩnh" khỏi bài đăng của tôi và nó vẫn có ý nghĩa. Ví dụ của Danny là một ví dụ hay. Thực tế, ngôn ngữ C có cùng một vấn đề: không có toán tử "giá trị của kiểu giá trị này", bởi vì nhiều giá trị có cùng biểu diễn. –

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