2015-05-02 17 views
8

Nhìn qua các nguồn Elixir Tôi thấy rằng nhân được định nghĩa như thế này:Elixir Macro: Power ** chức năng

@spec (number * number) :: number 
def left * right do 
    :erlang.*(left, right) 
end 

Tôi muốn thực hiện một chức năng ** để làm sức mạnh như một bài tập. Tuy nhiên, khi tôi cố gắng, tôi nhận được một ngoại lệ và tôi không thể tìm ra cách để làm điều đó một cách chính xác.

@spec (number ** number) :: number 
def left ** right do 
    :math.pow(left, right) 
end 

Luôn ném một lỗi như:

** (SyntaxError) iex:7: syntax error before: '*' 

Tôi đã cố gắng làm cho nó một macro, sử dụng unquote, sử dụng: "**" thay vì **. Không chắc chắn lý do tại sao điều này không hoạt động ...

Bất kỳ ý tưởng nào?

Trả lời

11

Các toán tử nhị phân được xác định trước trong Elixir, có nghĩa là trình phân tích cú pháp Elixir sẽ chỉ phân tích cú pháp các toán tử (trong đó, rõ ràng là bao gồm *). Bạn có thể xem danh sách các toán tử gần bằng this section của trình phân tích cú pháp. Có một số toán tử "miễn phí", đó là các toán tử mà Elixir có thể phân tích cú pháp nhưng không được sử dụng bởi chính ngôn ngữ đó (ví dụ: <~>), nhưng không có trong số đó là **.

Chỉ cần để chứng minh rằng các nhà khai thác parseable có thể làm những gì bạn muốn:

defmodule MyWeirdOperators do 
    def left <~> right do 
    :math.pow(left, right) 
    end 
end 

import MyWeirdOperators 
3 <~> 4 
#=> 81.0 
+0

Điều này đã cho tôi một trong những aha đó! khoảnh khắc ngày hôm qua, tôi nghĩ rằng tôi hiểu mô hình phù hợp với chức năng, nhưng nó sâu hơn so với các đối số phù hợp, nó phù hợp với rất nhiều! - Chỉ muốn nói lời cảm ơn :) –

+0

'**' từng là một toán tử quá tải, nhưng đã bị xóa. Điều này bởi vì mọi người _expect_ sử dụng nó như một toán tử 'pow', nhưng sẽ không thể sử dụng phép lũy thừa bên trong mệnh đề bảo vệ này. Tất cả các toán tử elixir mặc định * đều được phép trong các mệnh đề bảo vệ và khi có điều gì đó không phải là điều có thể gây nhầm lẫn cho mọi người. Vì vậy: '**' đã bị xóa. – Qqwy

3

Elixir không có một nhà điều hành **. Bạn không thể xác định toán tử kết xuất mới mà không thay đổi và biên dịch lại ít nhất the Elixir parserthe Macro module.

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