sách gpt4 ăn đã đi

Kiểm tra giá trị trả về và trả về(Kiểm tra giá trị trả về và trả về)

In lại Tác giả: trợ lý lỗi Thời gian cập nhật: 26-10-2023 20:17:55 29 4
mua khóa gpt4 giày nike



Đây có thể là một câu hỏi ngớ ngẩn, nhưng tôi đang tìm cách ngắn gọn để kiểm tra kết quả trả về của một hàm và nếu nó không đáp ứng một điều kiện nào đó thì trả về giá trị đó (tức là truyền nó đi).

Đây có thể là một câu hỏi ngu ngốc, nhưng tôi đang cố gắng tìm hiểu xem có cách nào ngắn gọn để kiểm tra xem hàm trả về gì không và nếu nó không thỏa mãn điều kiện, hãy trả về giá trị đó (tức là chuyển nó đi).


Để trả lời một câu hỏi có thể có ngay bây giờ, vâng, những gì tôi đang tìm kiếm tương tự như những gì ngoại lệ cung cấp. Tuy nhiên, với tư cách là một nhà phát triển nhúng, chi phí liên quan đến ngoại lệ (thật không may) là một chi phí quá cao để trả.

Bây giờ để trả lời một câu hỏi có thể xảy ra, vâng, điều tôi đang tìm kiếm là thứ gì đó tương tự với những gì ngoại lệ cung cấp. Tuy nhiên, với tư cách là một nhà phát triển nhúng, chi phí liên quan đến các trường hợp ngoại lệ (đáng buồn là) quá cao để phải trả.


Ví dụ,

Ví dụ,


Trạng thái lớp enum
{
ĐƯỢC RỒI,
LỖI1,
LỖI2,
LỖI3
};

Trạng thái foo1();
Trạng thái foo2();
Trạng thái foo3();

Thanh trạng thái()
{
Kết quả trạng thái;

kết quả = foo1();
nếu (kết quả != Trạng thái::OKAY) trả về kết quả;

kết quả = foo2();
nếu (kết quả != Trạng thái::OKAY) trả về kết quả;

kết quả = foo3();
nếu (kết quả != Trạng thái::OKAY) trả về kết quả;

trả về Trạng thái::ĐƯỢC;
}

Nếu tôi chỉ sử dụng bool làm giá trị trả về, cách viết tắt sẽ là như sau:

Nếu tôi chỉ sử dụng boolean làm giá trị trả về thì cách viết tắt là viết đoạn mã sau:


thanh bool()
{
nếu (!foo1()) trả về false;
nếu (!foo2()) trả về false;
nếu (!foo3()) trả về false;

trả về giá trị đúng;
}

Một mệnh đề if có tác dụng phụ như thế này được coi là mã lỗi, nhưng với tôi, điều này có vẻ dễ đọc và súc tích hơn so với các phép thử và gán biến cục bộ.

Các mệnh đề IF có tác dụng phụ như thế này được coi là có mùi mã, nhưng theo tôi, nó dễ đọc và ngắn gọn hơn so với các bài kiểm tra và phép gán biến cục bộ.


Có cách viết tắt nào để đạt được khả năng đọc tương tự như ví dụ thứ hai nhưng vẫn mang lại hiệu quả như ví dụ thứ nhất không?

Có cách nào nhanh chóng để đạt được khả năng đọc tương tự như ví dụ thứ hai nhưng có hiệu quả tương tự như ví dụ đầu tiên không?


Thêm câu trả lời

toán tử bool() có lẽ?

Có lẽ toán tử bool()?

Nếu bạn làm theo cách này bạn có thể thu gọn nó lại trả về foo1() && foo2() && foo3()

Nếu bạn làm điều này, bạn có thể thu gọn nó để trả về foo1()&&foo2()&&foo3()

Không có gì xuất hiện trong đầu. FWIW, tôi coi mã trong khối đầu tiên của bạn là thành ngữ. Nếu bạn cố gắng tự đưa sự trừu tượng của mình vào đây, nó có thể khiến việc bảo trì trở nên khó khăn hơn. Tôi hiểu sự thất vọng. Lần trước tôi làm việc với cURL, tôi có các phương thức trông giống như thế này.

Tôi không mong đợi bất cứ điều gì. BTW, tôi nghĩ mã trong khối đầu tiên của bạn là thành ngữ. Nếu bạn cố gắng áp dụng sự trừu tượng của riêng mình vào vấn đề này, nó có thể khiến việc bảo trì trở nên khó khăn hơn. Tôi hiểu sự thất vọng. Lần trước tôi sử dụng cURL, phương pháp của tôi trông như thế này.

kết quả = foo1(); nếu (kết quả != Trạng thái::OKAY) trả về kết quả; có thể trở thành nếu (tự động ret = foo1(); ret != Trạng thái::OKAY) trả về ret; Bạn có thể dễ dàng gói gọn điều đó trong một macro nếu muốn rút gọn cú pháp.

RESULT=foo1();If(Result!=Status::OK)Return Result; có thể trở thành If(AUTO RET=foo1();ret!=Status::OK)Return ret;, nếu bạn muốn hợp lý hóa cú pháp, bạn có thể Thật dễ dàng để gói nó trong một macro.

Nó đã được thêm vào trong C++17

Nó đã được thêm vào C++ 17

Khuyến nghị câu trả lời tuyệt vời

Một cách để thực hiện là sử dụng macro:

Một cách là sử dụng macro:


Trạng thái lớp enum
{
ĐƯỢC RỒI,
LỖI1,
LỖI2,
LỖI3
};

#define KIỂM TRA_TRẠNG THÁI(gọi_nơi)\
LÀM {\
Kết quả trạng thái = call_site;\
nếu (kết quả != Trạng thái::OKAY) trả về kết quả;\
} trong khi(0)

Trạng thái foo1();
Trạng thái foo2();
Trạng thái foo3();

Thanh trạng thái()
{
KIỂM TRA_TRẠNG THÁI(foo1());

KIỂM TRA_TRẠNG THÁI(foo2());

KIỂM TRA_TRẠNG THÁI(foo3());

trả về Trạng thái::ĐƯỢC;
}

Nếu bạn bối rối bởi làm ... trong khi(0), hãy kiểm tra điều này: do { ... } while (0) — nó có tác dụng gì?

Nếu bạn đang bối rối về DO... While(0), hãy kiểm tra điều này: Do{...}while(0) - nó dùng để làm gì?



Vì bạn đang sử dụng C++17, bạn có thể viết thanh() chức năng như thế này, theo tôi thì cũng không tệ lắm:

Vì bạn đang sử dụng C++17, bạn có thể viết hàm bar() như thế này, điều này không tệ, IMO:


Thanh trạng thái() {
nếu (kết quả tự động = foo1(); kết quả != Trạng thái::OKAY) trả về kết quả;
nếu (kết quả tự động = foo2(); kết quả != Trạng thái::OKAY) trả về kết quả;
nếu (kết quả tự động = foo3(); kết quả != Trạng thái::OKAY) trả về kết quả;
trả về Trạng thái::ĐƯỢC;
}

Hoặc, lambda cũng có thể hữu ích. Mặc dù tôi thấy nó ít hấp dẫn hơn trong tình huống cụ thể này:

Ngoài ra, Lambda cũng có thể có ích. Tuy nhiên, trong trường hợp cụ thể này, tôi thấy nó kém hấp dẫn hơn:


Thanh trạng thái() {
kết quả tự động = Trạng thái::ĐƯỢC;
tự động kiểm tra const = [&result](tự động foo) -> bool
{ trả về (kết quả = foo()) != Trạng thái::OKAY; };

nếu (kiểm tra(foo1)) trả về kết quả;
nếu (kiểm tra(foo2)) trả về kết quả;
nếu (kiểm tra(foo3)) trả về kết quả;
trả về kết quả;
}

Có lẽ việc viết functor của riêng bạn sẽ hiệu quả hơn:

Có lẽ việc viết chức năng của riêng bạn hoạt động tốt hơn:


Thanh trạng thái() {
cấu trúc {
Kết quả trạng thái;
bool toán tử()(Trạng thái (&foo)())
{ trả về (kết quả = foo()) != Trạng thái::OKAY; };
} kiểm tra{};

nếu (kiểm tra(foo1)) trả về kết quả kiểm tra;
nếu (kiểm tra(foo2)) trả về kết quả kiểm tra;
nếu (kiểm tra(foo3)) trả về kết quả kiểm tra;
trả về kiểm tra.kết quả;
}

Một cách khác là tận dụng khởi tạo tổng hợp, nhưng cách này có phần phức tạp hơn một chút.

Một cách tiếp cận khác là sử dụng khởi tạo tổng hợp, nhưng cách này hơi vượt trội về mặt thủ thuật.


Thanh trạng thái() {
cấu trúc chuyển đổi {
Kết quả trạng thái;
toán tử rõ ràng bool() const
{ trả về kết quả != Trạng thái::OKAY; }
} kiểm tra{};

nếu ((kiểm tra = chuyển đổi {foo1()})) trả về kết quả kiểm tra;
nếu ((kiểm tra = chuyển đổi {foo2()})) trả về kết quả kiểm tra;
nếu ((kiểm tra = chuyển đổi {foo3()})) trả về kết quả kiểm tra;
trả về kiểm tra.kết quả;
}

Ví dụ trực tiếp

Ví dụ trực tiếp



Dựa trên bình luận của @NathanOliver về câu hỏi của tôi, tôi đã viết ra giải pháp khả thi sau đây.

Dựa trên nhận xét của @NathanOliver về câu hỏi của tôi, tôi đã viết giải pháp khả thi sau đây.


#include 

Trạng thái lớp enum
{
ĐƯỢC RỒI,
QUÁ NHỎ,
QUÁ LỚN
};

bool toán tử!(Trạng thái s)
{
trả về s != Trạng thái::OKAY;
}

std::ostream& operator<<(std::ostream& os, Trạng thái s)
{
công tắc
{
trường hợp Trạng thái::OKAY:
os << "ĐƯỢC";
phá vỡ;
trường hợp Trạng thái::QUÁ NHỎ:
os << "QUÁ NHỎ";
phá vỡ;
trường hợp Trạng thái::QUÁ LỚN:
os << "QUÁ LỚN";
phá vỡ;
}

trả về hệ điều hành;
}

Thanh trạng thái (int a)
{
nếu (a < 5) trả về Trạng thái::QUÁ_NHỎ;
nếu (a > 10) trả về Trạng thái::QUÁ_LỚN;
nếu không thì trả về {};
}

Trạng thái foo(int a)
{
nếu (tự động r = bar(a); !r) trả về r;
nếu (tự động r = bar(a + 1); !r) trả về r;
nếu (tự động r = bar(a - 1); !r) trả về r;

trở lại {};
}

void test(int a)
{
kết quả tự động = foo(a);
std::cout << "foo(" << a << ") -> " << kết quả << std::endl;
}

int chính()
{
kiểm tra(8);
kiểm tra(5);
kiểm tra(10);

trả về 0;
}

Tôi đã đơn giản hóa việc kiểm tra có điều kiện của enum bằng cách nạp chồng toán tử !.

Các phương pháp đơn giản hóa việc kiểm tra có điều kiện của bảng liệt kê! nhà điều hành.


Thêm câu trả lời

KIỂM TRA_TRẠNG THÁI -> TRẢ LẠI NẾU TRẠNG THÁI KHÔNG ỔN.

Kiểm tra_Trạng_thái->Trả_về_Nếu_Trạng_thái_không_ổn.

Tôi thực sự đã viết một cái gì đó như thế này trước đây trong mã của tôi. Tuy nhiên, tôi đã bị bắn hạ vì sử dụng một macro như thế này sẽ tạo ra một "phương ngữ".

Tôi thực sự đã viết điều gì đó tương tự trong mã của mình trước đây. Tuy nhiên, tôi đã bị từ chối vì sử dụng macro như vậy sẽ tạo ra một "phương ngữ".

@PatrickWright Đúng vậy, nhưng liệu phương ngữ (đơn giản) có phải là điều tệ hại khi chúng được hiểu trong một nhóm không? Tôi cho rằng nếu OP tự mình viết mã, thì điều này có lẽ ổn. Nếu họ là một phần của một nhóm, thì phải có một kỹ sư cao cấp biết cách làm việc được chấp nhận chung trong nhóm.

@PatrickWright Điều đó đúng, nhưng liệu một phương ngữ (đơn giản) được hiểu trong một nhóm có phải là điều xấu không? Tôi muốn nói nếu OP tự viết mã thì điều này có thể ổn. Nếu họ là thành viên của một nhóm, cần phải có một kỹ sư cấp cao biết cách làm việc được chấp nhận rộng rãi trong nhóm.

Đây là một giải pháp tốt, nhưng tôi sẽ tuyên bố nếu như biểu thức khởi tạo hằng số: nếu(const auto result = ... vì chúng độc lập với nhau và không thay đổi. Khai báo một đối tượng const...

Đây là một giải pháp tốt, nhưng tôi sẽ khai báo biểu thức if init const:if(const Auto Result=... vì chúng độc lập với nhau và sẽ không thay đổi. Khai báo các hằng số đối tượng...

@Casey Cảm ơn bạn đã gợi ý, và tôi đồng ý rằng đây là một quy tắc chung tốt. Tuy nhiên, đối với một câu lệnh if một dòng, mà tôi nghĩ chỉ tốt khi kết hợp với một câu lệnh return (một cách để ngăn chặn việc viết phạm vi sâu hơn), tôi nghĩ rằng nó không mang lại nhiều giá trị. Tôi thậm chí còn cho rằng trong một số trường hợp, như trường hợp này nhưng cũng có tham số hàm, thì tốt nhất là nên bỏ qua.

@Casey Cảm ơn lời khuyên, nhìn chung tôi đồng ý rằng đó là một nguyên tắc chung. Tuy nhiên, đối với một câu lệnh if một dòng, mà tôi nghĩ chỉ có ít giá trị nếu được kết hợp với một câu lệnh return duy nhất (một cách để ngăn việc viết phạm vi sâu hơn), tôi thấy nó có rất ít giá trị. Tôi thậm chí còn lập luận rằng trong một số trường hợp, như trường hợp này, nhưng cũng với các tham số hàm, thực sự tốt hơn là nên bỏ qua nó.

29 4 0
trợ lý lỗi
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress