2012-05-07 29 views
16

Tôi đang cố gắng nhập khẳng định từ một số []Node, đến []Symbol. Trong mã của tôi, Symbol triển khai giao diện Node.Tôi có thể gõ khẳng định một lát các giá trị giao diện không?

Dưới đây là một số mã xung quanh:

43 func applyLambda(args []Node, env Env) Node { 
44  if len(args) > 2 { 
45   panic("invalid argument count") 
46  } 
47  fixed, rest := parseFormals(args.([]Symbol)) 
48  return Func{ 
49   Body: args[1], 
50   FixedVarNames: fixed, 
51   RestVarName: rest, 
52  } 
53 } 

Đây là lỗi tôi nhận được:

./builtins.go:47: invalid type assertion: args.([]Symbol) (non-interface type []Node on left) 

tôi chắc chắn rằng có một lý do chính đáng cho việc này. Cách tốt nhất để tiến hành là gì?

Trả lời

15

Nói rằng x.(T) biến x phải thuộc loại giao diện, vì chỉ dành cho các biến loại kiểu giao diện kiểu động không cố định. Và trong khi Node là một giao diện, []Node thì không. Một lát là một loại không phân biệt, giao diện. Vì vậy, nó chỉ không có ý nghĩa để giả định một lát của các giá trị giao diện là một giao diện quá.

Loại Node có định nghĩa rõ ràng trong mã của bạn và do đó là giao diện. Bạn đã chỉ định danh sách các phương thức cho nó. Loại []Node không giống như vậy. Nó định nghĩa phương thức nào?

Tôi hiểu bạn đến từ đâu với điều này. Nó có thể là một phím tắt hữu ích, nhưng chỉ không có ý nghĩa. Nó giống như mong đợi syms.Method() hoạt động khi loại của syms[]SymbolMethod là dành cho Symbol.

Thay thế dòng 47 với mã này làm những gì bạn muốn:

symbols := make([]Symbol, len(args)) 
for i, arg := range args { symbols[i] = arg.(Symbol) } 
fixed, rest := parseFormals(symbols) 
+0

Tôi không đồng ý với tình cảm của bạn "Vì vậy, nó chỉ không có ý nghĩa để giả định một lát giá trị giao diện là một giao diện quá". Chuyển đổi là chuyển đổi - giao diện là giao diện. Chúng là những khái niệm riêng biệt (ít nhất là trong tâm trí của tôi). Các tác giả có thể quyết định hỗ trợ chuyển đổi từ '[] Node' thành' [] Symbol', nhưng chúng không phải vì nó quá tốn kém và các chuyển đổi như vậy không phải là một mẫu lập trình chung. Về mặt lý thuyết, bất kỳ chuyển đổi nào không đòi hỏi sự mâu thuẫn cũng không phải là một vấn đề có ý nghĩa - nhưng các nhà thiết kế ngôn ngữ cần phải chọn chuyển đổi để đưa vào ngôn ngữ. –

+1

Tôi không thể nói chắc chắn những gì tác giả Go nghĩ về vấn đề này, nhưng tôi vẫn nghĩ rằng giả định của tôi là sự thật. Bạn đúng rằng chuyển đổi này quá tốn kém, nhưng tôi không nghĩ đó là lý do khiến việc đó trở thành bất hợp pháp. Như tôi đã nói, trong Go slice là một kiểu. Bạn có thể nói 'type Nodes [] Node'. 'Nodes' có phải là loại giao diện không? Vì vậy, tôi thấy đó là lý do chúng tôi không thể xác nhận các biến kiểu '[] Node'. Bạn có muốn thực hiện cuộc thảo luận này trên danh sách gửi thư golang-hạt không? – Mostafa

+0

@Atom: Câu hỏi không hỏi về chuyển đổi; nó hỏi về xác nhận kiểu – newacct

5

Đi không cho phép điều này. Bạn cần chuyển đổi Node thành Symbol riêng lẻ.

Lý do tại sao nó không được phép là []Node[]Symbol có các biểu diễn khác nhau, do đó chuyển đổi sẽ cần phải cấp phát bộ nhớ cho []Symbol.

+0

điều là, câu hỏi được thậm chí không hỏi về chuyển đổi. nó hỏi về một xác nhận kiểu – newacct

+0

Bạn nói đúng, câu trả lời của tôi là khó hiểu. Tôi đã xóa câu cuối cùng khỏi câu trả lời của mình. –

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