2015-06-02 16 views
13

Tôi tò mò khi tôi nên sử dụng mẫu khớp với mệnh đề bảo vệ khi xác định hàm.Elixir: Pattern Match hoặc Guard

Ví dụ với mô hình kết hợp:

defmodule Exponent do 
    def power(value, 0), do: 1 
    def power(value, n), do: value*power(value, n-1) 
end 

vs bảo vệ khoản:

defmodule Exponent do 
    def power(value, n) when n==0, do: 1 
    def power(value, n), do: value*power(value, n-1) 
end 

Ý tôi là cả hai tạo ra kết quả tương tự nhưng là một giải pháp ưa thích hơn người kia? Và nếu vậy tại sao?

Tôi là người mới đến Elixir, do đó, câu trả lời cho câu hỏi này không dễ dàng đối với tôi (chưa). Cảm ơn trước.

+0

Bạn có quan sát thấy bất kỳ khác biệt hiệu suất nào trong một cấu trúc so với cấu trúc kia không? Hỏi xem một người có được ưu tiên hơn những người khác đánh tôi như một ví dụ tuyệt vời về câu hỏi muốn có ý kiến ​​nếu không có sự khác biệt về hiệu suất. Bỏ phiếu để đóng. –

+0

Tôi thực sự rất mới Tôi chưa khám phá ra cách để chuẩn bị loại điều này ... Tôi cũng không thấy những câu hỏi tương tự nên tôi quyết định hỏi một cách rõ ràng. – aren55555

+0

Có thể có sự khác biệt giữa triển khai thực hiện này và triển khai khác nhưng không có bất kỳ ngữ cảnh nào khó nói. Ngay bây giờ bạn đang hỏi một câu hỏi tương tự như "tốt hơn, chuối hay dâu tây?" –

Trả lời

17

Vệ sĩ mạnh hơn so khớp mẫu, nhưng chúng giới thiệu một lớp phức tạp có thể không cần thiết. Đối với các kiểm tra bình đẳng đơn giản như trong ví dụ của bạn, chúng phải tương đương về hiệu suất. Tôi khuyên bạn nên cố gắng sử dụng mẫu khớp trước để giữ cho mọi thứ đơn giản. Sau đó, bạn có thể quay lại điều khoản bảo vệ nếu cần thiết. Tuy nhiên, đôi khi nó có thể có ý nghĩa để làm khác khi nó hỗ trợ khả năng đọc, ví dụ:

def sign(x) when x < 0, do: -1 
def sign(x) when x == 0, do: 0 
def sign(x) when x > 0, do: 1 

Tôi cho rằng trường hợp sử dụng "đúng" cho toán tử bình đẳng trong mệnh đề bảo vệ là khi nó được sử dụng như một phần của các biểu thức phức tạp hơn, ví dụ:

def divisible?(x, divisor) when rem(x, divisor) == 0, do: true 
def divisible?(_x, _divisor), do: false