2016-05-23 15 views
5

Tôi đang ở MATLAB R2014b và có một câu hỏi mà tôi sẽ minh họa bằng ví dụ sau.Tại sao bạn có thể nhập gói * sau * bằng nội dung của nó trong một chức năng?

MWE có thể được thực hiện như sau hoặc download it as a .zip file here.

Tạo một thư mục gói +test trên con đường của bạn với bốn tập tin hàm trong nó:

+test 
    a.m 
    b.m 
    c.m 
    d.m 

Nội dung a.m:

function a 
disp 'Hello World!' 

Nội dung b.m:

function b 
a 

Nếu bạn chạy b từ đồng dòng mmand, bạn sẽ phải nhập gói test trước tiên (import test.*) hoặc chạy test.b.

Chạy b sẽ dẫn đến lỗi do phạm vi chức năng b không chứa hàm a. Chúng ta phải nhập nó trước khi nó có thể được sử dụng. Đối với điều này tôi đã tạo c.m:

function c 
import test.* 
a 

Hiện đang chạy c hoạt động tốt.

Bây giờ là câu hỏi của tôi. Nếu tôi thay đổi c.m thành (được lưu trong d.m):

I.e. lệnh nhập được cấp sau cuộc gọi đến chức năng gói a. Chạy d vẫn hoạt động tốt, như thể vị trí của lệnh nhập trong d.m không quan trọng. Quá trình nhập dường như đã xảy ra trước khi gọi hàm a, trong đó ở d.m xảy ra trên dòng trước khi nhập.

Tại sao điều này xảy ra. Đây có phải là hành vi dự định và sử dụng của nó là gì? MATLAB đọc một tập tin .m và xử lý nó như thế nào? Và nhiều chủ đề khác, nhưng nói chung: làm cách nào để nhập các gói được xử lý bằng các ngôn ngữ khác nhau so với MATLAB, thứ tự các lệnh có quan trọng không?

Kết luận ưu tiên của tôi dựa trên nhận xét: Có lẽ cách tốt nhất là chỉ sử dụng chức năng nhập tại hoặc gần đầu mã MATLAB. Điều này giúp hiển thị rõ ràng nội dung đã nhập có sẵn trong toàn bộ phần tử (ví dụ: chức năng). Nó cũng ngăn cản giả định không chính xác rằng trước khi nhập, nội dung chưa có sẵn hoặc đề cập đến một điều khác có cùng tên.

+0

@thewaywewalk Tôi chắc chắn đó không phải là sự hiểu lầm của tôi. Tôi đã rất cẩn thận với các gói đã nhập trước khi chỉnh sửa 'b.m'. Tôi đã sử dụng 'clear all',' clear classes' và 'clear import' trước khi thực hiện bất kỳ bước nào, nhưng đánh giá từ tài liệu về' import', điều này không cần thiết: mọi chức năng đều có không gian làm việc và danh sách nhập riêng. điều này với 'L = import'). Ngay cả khi không gian làm việc MATLAB chính có một gói được nhập, nó sẽ không được chuyển tới bất kỳ hàm nào bạn gọi từ dòng lệnh. Lưu ý: các tập lệnh hoạt động trong không gian làm việc mà chúng được gọi, vì vậy chúng kế thừa danh sách nhập từ đó. – Erik

+0

Tôi đã chỉnh sửa câu hỏi. Bây giờ 'b.m' không được thay đổi, thay vào đó hai tệp' c.m' và 'd.m' đã được thêm vào. Tôi cũng đã thêm MWE thành tệp .zip cho những ai muốn tự mình thử. Hàm 'd.m' bây giờ là hàm có hành vi thú vị. – Erik

+2

Tôi hiểu sự cố của bạn ngay bây giờ. Tôi không có câu trả lời mặc dù, nhưng lệnh nhập khẩu dường như được xử lý trước khi bất cứ điều gì khác được gọi. Tài liệu nói *** Không sử dụng nhập khẩu trong các câu lệnh có điều kiện bên trong một hàm. MATLAB xử lý trước câu lệnh import trước khi đánh giá các biến trong câu lệnh điều kiện. – thewaywewalk

Trả lời

3

MATLAB thực hiện phân tích mã tĩnh trước khi đánh giá một hàm để xác định các biến/hàm được sử dụng bởi hàm đó. Việc đánh giá các câu lệnh import là một phần của phân tích mã tĩnh này. Điều này là do thiết kế bởi vì nếu bạn import một gói và sau đó sử dụng chức năng của nó, MATLAB cần phải biết điều này trong quá trình phân tích mã tĩnh. Kết quả là, bất kể trong đó bạn đặt câu lệnh import trong hàm của mình, nó sẽ có tác dụng tương tự như khi nó ở đầu hàm.

Bạn có thể dễ dàng kiểm tra điều này bằng cách xem sản phẩm của import sẽ liệt kê tất cả các gói đã nhập hiện tại.

+test/a.m

function a(x) 
    disp(import) 
    import test.* 
end 

test.a() 

% test.* 

Đó là lý do the documentation states-không đưa một tuyên bố có điều kiện import trong một.

Không sử dụng import trong câu lệnh có điều kiện bên trong một hàm. MATLAB xử lý trước câu lệnh import trước khi đánh giá các biến trong câu lệnh có điều kiện.

function a(x) 
    disp(import) 
    if x 
     import test.* 
    else 
     import othertest.* 
    end 
end 

test.a() 

% test.* 
% othertest.* 

Cách duy nhất để tránh những hành vi này là cho phép các mã phân tích tĩnh để xác định (không có nghi ngờ gì nữa) rằng một tuyên bố import sẽ không được thực thi. Chúng ta có thể làm điều này bằng cách có câu lệnh điều kiện của chúng ta đơn giản là một giá trị logic.

function a() 
    disp(import) 
    if true 
     import test.* 
    else 
     import othertest.* 
    end 
end 

test.a() 

% test.* 

Theo như nhập khẩu so với các ngôn ngữ khác, nó thực sự phụ thuộc vào ngôn ngữ. Trong Python ví dụ, bạn phải đặt importtrước khi truy cập vào nội dung mô-đun. Theo kinh nghiệm của tôi, đây là trường hợp điển hình nhưng tôi chắc chắn có nhiều ngoại lệ. Mọi ngôn ngữ sẽ khác nhau.

+1

Chỉ cần thêm vào đó trong Java, bạn thường thêm nhập vào đầu mỗi tập tin. Java là không chính xác như Matlab mặc dù. trong C++ từ khóa 'using' thực hiện điều tương tự, và thường được thêm vào đầu mỗi tập tin (sau ** # include ** s). Tread rất cẩn thận khi sử dụng các hàng nhập khẩu này. Trong trường hợp có nhiều hàm có cùng tên. Trong trường hợp đó, tốt hơn là sử dụng ký hiệu chấm. Tôi khuyên bạn nên sử dụng nhập khẩu ở đầu mỗi phạm vi và chỉ nhập các chức năng duy nhất. – patrik

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