Tại sao biểu thức ghép?


10

Đây là một ví dụ từ một cuốn sách tôi đang đọc:

volume = begin
    len = 10
    breadth = 20
    height = 30
    len * breadth * height
end

Tại sao tôi cần biểu thức ghép ?? Tôi chỉ có thể viết volume = 10 * 20 * 30hoặc volume = len * breadth * heightviết một hàm cho hàm đó hoặc hàm ẩn danh ...

Tại sao tôi sử dụng beginend? Hoặc câu hỏi có lẽ tốt hơn: Khi nào tôi sử dụng chúng, vì tôi đoán ví dụ trên từ cuốn sách có lẽ không tốt lắm.


1
Cuốn sách đó là gì? như bạn cũng không phải là ví dụ không đặc biệt tốt
Michael K. Borregaard

"Học Julia", như có sẵn ở đây: epdf.pub/learning-julia.html (trang 127)
Georgery

Câu trả lời:


4

Tôi đoán có nhiều tình huống trong đó begin ... endcác khối là tiện dụng, nhưng như bạn lưu ý, bạn cũng có thể thường đạt được hiệu ứng tương tự với các cấu trúc khác, chẳng hạn như các hàm, v.v.

begin ... endKhối có thể được sử dụng để làm gì?

  • Để đơn giản là "chứa" biến và tên của họ: len, breadth, và heightsẽ chỉ tồn tại trong khối và không gây ô nhiễm không gian tên xung quanh.
  • Để áp dụng các macro cho một khối mã thay vì các câu lệnh riêng lẻ. Ví dụ @inbounds begin <all my code without bounds checking goes here> endhoặc gói một @time begin ... endxung quanh một đoạn mã.
  • Để tạo một phạm vi cục bộ trong phạm vi toàn cầu xung quanh ( ví dụ để tránh nhầm lẫn phạm vi toàn cầu ). (Lưu ý rằng như đã được chỉ ra trong các ý kiến begin ... endnào không giới thiệu một phạm vi địa phương, nhưng lập luận giữ cho tương tự let ... endkhối.)

Cụ thể, điểm thứ hai là những gì tôi sử dụng chúng cho mã của mình.


Tôi cũng đã phải trấn an bản thân mình, nhưng beginkhối làm không giới thiệu phạm vi . Mặt khác, họ chuyển đổi một chuỗi các câu lệnh thành một biểu thức, có thể hữu ích nếu bạn tạo mã với / từ một macro.
phipsgabler

1
Ồ, cảm ơn, về vấn đề đó tôi đã nhầm lẫn nó với let ... endviệc giới thiệu một phạm vi địa phương. Sẽ sửa câu trả lời của tôi.
crstnbr

Tôi luôn đưa ra giả định sai tương tự :) Đó chỉ là những gì người ta mong đợi.
phipsgabler

1
@crstnbr Viên đạn đầu tiên của bạn vẫn còn sai lệch. Dường như vẫn nói rằng begincác khối giới thiệu một phạm vi địa phương.
Cameron Bieganek

7

Để khái quát những gì mọi người khác đã nói: các khối cho phép bạn chuyển đổi danh sách các câu lệnh (cụm từ "cú pháp" không có giá trị, nghĩa là không thể gán) thành một biểu thức (một "cụm từ" đại diện cho các giá trị và có thể được gán ).

Ví dụ, trong khi bạn không nên, bạn có thể viết

x = begin
    s = 0
    for i = 1:10
        s += i^2
    end
    s
end

để gán xcho kết quả của một hoạt động lặp. (Với hạn chế là câu lệnh cuối cùng trong chuỗi phải thực sự là một biểu thức - nếu không, bạn sẽ không có giá trị nào cho biểu thức.)

Một trường hợp sử dụng hợp pháp của điều này được tạo ra mã. Ví dụ: bạn có thể biến

x = @somthing bla blub

vào

x = begin
   (stuff involving bla and blub)
end

minh bạch cho người dùng, trong khi @somethingcó thể tự do tạo ra bất kỳ cấu trúc ngôn ngữ nào.

Hoặc nếu bạn muốn viết một hàm ẩn danh với phần thân dài hơn (và không sử dụng functionbiểu mẫu):

f = x -> begin
   ...
end

1
Một sự làm rõ nhỏ: Trong Julia, các câu lệnh có giá trị và có thể được chỉ định. Vì vậy, bạn có thể làm x = y = 1, a = if false endb = for i in 1:2 end, sau đó xcó giá trị 1, abcả hai đều có giá trị nothing.
Cameron Bieganek

Ồ, đây là một ví dụ hữu ích hơn về việc gán giá trị của if-elsecâu lệnh : a = if false; 1 else 2 end. Trong trường hợp này, abằng 2.
Cameron Bieganek

1
Phải, họ có giá trị và cũng là biểu hiện công nghệ. Chuyển nhượng là một biểu thức, vì về cơ bản nó là setproperty!/ setindex!và theo truyền thống, nó là một thứ để nó có giá trị (trong các ngôn ngữ giống như C). Tương tự if-else, đó là một biểu thức trong một vài ngôn ngữ. Nhưng forifkhông elsecó giá trị "mặc định" nothing, tôi thấy đó chỉ là một vật phẩm.
phipsgabler

6

Một cách sử dụng cho các khối này là trong sự hiểu biết:

A = [ begin
           x = y^2
           x - x^2 + 2
         end
         for y = 1:5 ]

Thay vào đó, bạn có thể tạo một hàm và sử dụng nó bên trong phần hiểu, nhưng đôi khi điều này thuận tiện. Nó được sử dụng bất cứ khi nào bạn muốn sử dụng một khối mã nhiều dòng ở đâu đó, ví dụ để chuyển làm đối số cho macro (thường được sử dụng cho @testsetthư viện tiêu chuẩn Kiểm tra).


Không phản đối quan điểm của bạn nhưng người ta chỉ có thể viết y^2 - y^4 + 2trong trường hợp này. Có lẽ sẽ tốt hơn nếu đưa ra một ví dụ trong đó hai (hoặc nhiều) bước thực sự cần thiết.
crstnbr

@crstnbr bạn đúng, nhưng ban đầu tôi chỉ sử dụng ví dụ từ cuốn sách và chỉ đơn giản là quan tâm đến việc sử dụng hợp lý sẽ là gì.
Georgery

1
Giống như, để tiết kiệm tính toán một số giá trị trung gian đắt tiền hai lần.
phipsgabler

5

Nói một cách đơn giản: Bắt đầu, chỉ đơn giản là biểu thị một khối mã (xem các tài liệu về điều này: https://docs.julialang.org/en/v1/base/base/#begin ).

Trong ví dụ trên, không rõ ràng rằng có bất kỳ giá trị nào khi sử dụng khối bắt đầu so với khai báo hàm.

Tôi không thấy từ khóa đó được sử dụng rất nhiều trong mã và cá nhân tôi chưa bao giờ sử dụng nó trong thực tế. Đề nghị của tôi để chỉ sử dụng một chức năng vì nó sẽ làm điều tương tự.


Tôi chưa sử dụng Julia, nhưng đây chính xác là những gì tôi đang nghĩ. Tuy nhiên, khi ngôn ngữ được thiết kế (có lẽ rất thông minh) mọi người hẳn đã có một ý tưởng trong đầu, phải không?
Georgery

Tôi đồng ý với @logankilpatrick rằng trong nhiều trường hợp bạn muốn sử dụng các chức năng thay thế. Nhưng tôi nghĩ có những lý do cho sự tồn tại của các khối này (xem câu trả lời của tôi).
crstnbr

@Georgery Đôi khi biến một chuỗi các câu lệnh thành một biểu thức là một điều hữu ích (xem progntrong LISP).
phipsgabler

1
như bạn lưu ý chính xác, nó có vẻ vô nghĩa trong bối cảnh
Michael K. Borregaard
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.