Sự khác biệt giữa “điều kiện tiên quyết” và “khẳng định” nhanh chóng?


105

Sự khác biệt giữa Swift precondition(condition: Bool, message: String)assert(condition: Bool, message: String)Swift là gì?

Cả hai người họ trông giống nhau đối với tôi. Trong ngữ cảnh nào chúng ta nên sử dụng cái này thay cho cái kia?

Câu trả lời:


125

assertlà để kiểm tra sự tỉnh táo trong quá trình thử nghiệm, trong khi đó preconditionlà để đề phòng những điều, nếu chúng xảy ra, có nghĩa là chương trình của bạn không thể tiến hành một cách hợp lý.

Vì vậy, chẳng hạn, bạn có thể thực asserthiện một phép tính nào đó có kết quả hợp lý (chẳng hạn như trong một số giới hạn), để nhanh chóng tìm xem bạn có lỗi hay không. Nhưng bạn sẽ không muốn giao hàng với điều đó, vì kết quả ngoài giới hạn thể hợp lệ và không quan trọng nên sẽ không làm ứng dụng của bạn bị hỏng (giả sử bạn chỉ sử dụng nó để hiển thị tiến trình trong thanh tiến trình).

Mặt khác, kiểm tra xem chỉ số con trên một mảng có hợp lệ khi tìm nạp một phần tử là a precondition. Không có hành động tiếp theo hợp lý nào để đối tượng mảng thực hiện khi được yêu cầu một chỉ số con không hợp lệ, vì nó phải trả về một giá trị không phải là tùy chọn.

Toàn văn từ tài liệu (thử nhấp vào tùy chọn assertpreconditiontrong Xcode):

Điều kiện tiên quyết

Kiểm tra một điều kiện cần thiết để đạt được tiến bộ.

Sử dụng chức năng này để phát hiện các điều kiện ngăn cản chương trình tiếp tục ngay cả trong mã vận chuyển.

  • Trong sân chơi và bản dựng -Onone (mặc định cho cấu hình Gỡ lỗi của Xcode): nếu conditiongiá trị là false, hãy dừng thực thi chương trình ở trạng thái có thể gỡ lỗi sau khi in message.

  • Bản dựng In -O (mặc định cho cấu hình Bản phát hành của Xcode): nếu conditionđánh giá là sai, hãy dừng thực thi chương trình.

  • Các bản dựng In -Ounchecked, conditionkhông được đánh giá, nhưng trình tối ưu hóa có thể cho rằng nó sẽ đánh giá true. Việc không đáp ứng giả định đó trong các bản dựng -Ounchecked là một lỗi lập trình nghiêm trọng.

Khẳng định

Khẳng định kiểu C truyền thống với một thông báo tùy chọn.

Sử dụng chức năng này để kiểm tra sự tỉnh táo nội bộ đang hoạt động trong quá trình thử nghiệm nhưng không ảnh hưởng đến hiệu suất của mã vận chuyển. Để kiểm tra việc sử dụng không hợp lệ trong các bản phát hành; xem precondition.

  • Trong sân chơi và bản dựng -Onone (mặc định cho cấu hình Gỡ lỗi của Xcode): nếu conditiongiá trị là false, hãy dừng thực thi chương trình ở trạng thái có thể gỡ lỗi sau khi in message.

  • Các bản dựng In -O (mặc định cho cấu hình Bản phát hành của Xcode), conditionkhông được đánh giá và không có hiệu ứng.

  • Các bản dựng In -Ounchecked, conditionkhông được đánh giá, nhưng trình tối ưu hóa có thể cho rằng nó sẽ đánh giá true. Việc không đáp ứng giả định đó trong các bản dựng -Ounchecked là một lỗi lập trình nghiêm trọng.


2
"Nhưng bạn sẽ không muốn giao hàng với điều đó, vì kết quả ngoài giới hạn thể hợp lệ và không quan trọng nên không làm ứng dụng của bạn bị hỏng", điều đó rất mơ hồ đối với tôi. Vui lòng bạn có thể bao gồm một ví dụ chính xác? Có lẽ một số mã.
Honey,

2
Trả lời câu hỏi của bạn, cá nhân tôi sử dụng các xác nhận để nắm bắt những điều không nên xảy ra trong bản dựng của tôi khi tôi đang viết và thử nghiệm nó. Hãy tưởng tượng một câu lệnh bảo vệ đọc JSON ở nơi data["name"]không tồn tại, nhưng nó nên. Có một xác nhận bên trong bảo vệ..else {} sẽ giúp tôi bắt lỗi bằng cách gặp sự cố và đưa tôi đến vấn đề. Tương tự, nếu mã này đang được sản xuất, xác nhận sẽ không làm hỏng chương trình và bất kỳ mã dự phòng nào mà tôi đã sử dụng ( return nil) sẽ tiếp quản.
Alec O

1
Bạn không nên kiểm tra chỉ mục và không làm bất cứ điều gì thay vì làm hỏng toàn bộ ứng dụng?
Iulian Onofrei

Có, bạn nên kiểm tra chỉ mục, nhưng đôi khi mọi người đều trượt lên và việc sử dụng các xác nhận giúp bạn nhận ra rằng bạn nên kiểm tra chỉ mục khi bạn quên.
Victor Engel

90

Tôi thấy các khẳng định của Swift - hướng dẫn còn thiếu rất hữu ích

                        debug   release   release
function                -Onone  -O       -Ounchecked
assert()                YES     NO        NO
assertionFailure()      YES     NO        NO**
precondition()          YES     YES       NO
preconditionFailure()   YES     YES       YES**
fatalError()*           YES     YES       YES

Và từ các cuộc thảo luận thú vị về Swift Evolution

- khẳng định: kiểm tra mã của riêng bạn để tìm lỗi nội bộ

- điều kiện tiên quyết: để kiểm tra xem khách hàng của bạn đã cung cấp cho bạn các đối số hợp lệ chưa.

Ngoài ra, bạn cần phải cẩn thận về những gì sẽ sử dụng, xem phần khẳng định Mức độ thất bại và Tối ưu hóa


Bạn có thể nói rõ hơn về sự khác biệt của mã riêng và máy khách? Đối với khách hàng, bạn có nghĩa là giống như chèn các số vào nơi một Chuỗi được mong đợi? Điều đó không nên được xử lý bằng một số xử lý lỗi đơn giản?
Honey

@Honey Tôi nghĩ anh ấy có ý nghĩa về các đối số / kết quả từ việc gọi API mạng hoặc các plugin của riêng khách hàng.
Chen Li Yong

Khách hàng sẽ là người sử dụng mã của bạn, giả sử bạn đang viết thư viện và một lập trình viên chuyển dữ liệu không hợp lệ. Bạn sẽ không muốn tiếp tục một cách duyên dáng vì đó có thể được coi là một lỗi lập trình nghiêm trọng. Bạn có thể không bao giờ gặp sự cố trên dữ liệu API mạng không hợp lệ vì điều đó rất không hữu ích cho người dùng.
bompf

@ onmyway133: Từ Trợ giúp nhanh Xcode, tôi nghĩ precondition()preconditionFailure()đang có những hành vi tương tự . Sự khác biệt giữa các chức năng này là: preconditioncần một điều kiện bên trong, trong khi preconditionFailurechỉ cần ném ra ngoài.
nahung89

12

Các preconditionhoạt động trong chế độ phát hành, do đó bạn khi bạn gửi ứng dụng của bạn và các điều kiện tiên quyết không ứng dụng sẽ chấm dứt. Assertchỉ hoạt động ở chế độ gỡ lỗi như mặc định.

Tôi đã tìm thấy lời giải thích tuyệt vời này khi sử dụng nó trên NSHipster:

Khẳng định là một khái niệm vay mượn từ logic cổ điển. Trong logic, khẳng định là phát biểu về các mệnh đề trong một bằng chứng. Trong lập trình, các xác nhận biểu thị các giả định mà người lập trình đã thực hiện về ứng dụng tại nơi chúng được khai báo.

Khi được sử dụng với khả năng điều kiện trước và điều kiện sau, mô tả kỳ vọng về trạng thái của mã khi bắt đầu và kết thúc thực thi một phương thức hoặc chức năng, các xác nhận tạo thành một hợp đồng. Các xác nhận cũng có thể được sử dụng để thực thi các điều kiện tại thời điểm chạy, nhằm ngăn chặn việc thực thi khi một số điều kiện tiên quyết không thành công.


Có thể bật và tắt xác định bằng cờ trình biên dịch; họ có thể hoạt động trong mã được vận chuyển.
Pétur Ingi Egilsson

6

điều kiện tiên quyết

func precondition(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

Kiểm tra một điều kiện cần thiết để đạt được tiến bộ.

  1. Sử dụng chức năng này để phát hiện các điều kiện ngăn cản chương trình tiếp tục ngay cả trong mã vận chuyển.
  2. Trong các sân chơi và bản dựng -Onone (mặc định cho cấu hình Gỡ lỗi của Xcode): nếu điều kiện đánh giá là sai, hãy dừng thực thi chương trình ở trạng thái có thể gỡ lỗi sau khi in thông báo.
  3. Các bản dựng In -O (mặc định cho cấu hình Bản phát hành của Xcode): nếu điều kiện đánh giá là sai, hãy dừng thực thi chương trình.
  4. Các bản dựng In -Ounchecked, điều kiện không được đánh giá, nhưng trình tối ưu hóa có thể cho rằng nó sẽ đánh giá thành true. Việc không đáp ứng giả định đó trong các bản dựng -Ounchecked là một lỗi lập trình nghiêm trọng.

khẳng định

func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

Khẳng định kiểu C truyền thống với một thông báo tùy chọn.

  1. Sử dụng chức năng này để kiểm tra sự tỉnh táo nội bộ đang hoạt động trong quá trình thử nghiệm nhưng không ảnh hưởng đến hiệu suất của mã vận chuyển. Để kiểm tra việc sử dụng không hợp lệ trong các bản phát hành; xem điều kiện tiên quyết.

  2. Trong các sân chơi và bản dựng -Onone (mặc định cho cấu hình Gỡ lỗi của Xcode): nếu điều kiện đánh giá là sai, hãy dừng thực thi chương trình ở trạng thái có thể gỡ lỗi sau khi in thông báo.

  3. Các bản dựng In -O (mặc định cho cấu hình Bản phát hành của Xcode), điều kiện không được đánh giá và không có hiệu ứng
  4. Các bản dựng In -Ounchecked, điều kiện không được đánh giá, nhưng trình tối ưu hóa có thể cho rằng nó sẽ đánh giá thành true. Việc không đáp ứng giả định đó trong các bản dựng -Ounchecked là một lỗi lập trình nghiêm trọng
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.