Thành ngữ kiểm tra Dart null hoặc phương pháp hay nhất là gì?


82

Tôi có biểu mẫu phân công & kiểm tra rỗng sau đây để tránh tra cứu hai lần trong bản đồ của mình.
Có cách nào hay hơn hoặc thành ngữ hơn để làm điều này trong Dart không?

bool isConnected(a, b){
  List list;
  return (
    ((list = outgoing[a]) != null && list.contains(b)) ||
    ((list = incoming[a]) != null && list.contains(b))
  );
}

Câu trả lời:


116

Kể từ Dart 1.12, các toán tử không nhận biết có sẵn cho loại tình huống này:

bool isConnected(a, b) {
  bool outConn = outgoing[a]?.contains(b) ?? false;
  bool inConn = incoming[a]?.contains(b) ?? false;
  return outConn || inConn;
}

Các ?.nhà khai thác ngắn mạch để null nếu phía bên trái tay là null, và các ??nhà điều hành trả về bên trái tay nếu nó không phải là null, và phía bên tay phải ngược lại.

Tuyên bố

outgoing[a]?.contains(b)

do đó sẽ đánh giá nullnếu outgoing[a]null, hoặc kết quả boolean của contains(b)nếu nó không.

Điều đó có nghĩa là câu lệnh kết quả sẽ là một trong những câu sau:

bool outConn = null ?? false; // false
bool outConn = false ?? false; // false
bool outConn = true ?? false; // true

Điều tương tự cũng áp dụng cho inConnboolean, có nghĩa là cả hai inConnoutConnđều được đảm bảo là khác rỗng, cho phép chúng tôi trả về kết quả của ||việc nhập cả hai.


Viết outgoing[a]?.contains(b)là nguy hiểm, ít nhất là với ngữ nghĩa Groovy, bởi vì khi nào outgoingthì nulltoàn bộ biểu thức sẽ đánh giá null. Vì vậy, trên thực tế, bạn có thể nhận được một cái gì đó giống như return (null || true), sẽ chuyển sang chế độ đã chọn.
Ladicek

Cảm ơn vì liên kết vấn đề mở.
z5h

@Ladicek Cảm ơn bạn đã chỉ ra điều đó. Tôi đã kết hợp toán tử null-Coalescing ( ??) vào câu trả lời cập nhật của mình để giải quyết vấn đề đó.
Pixel Elephant


Để kiểm tra Trường đối tượng chỉ cần viết object?.field ?? true. Nơi sự thật có thể là bất cứ điều gì bạn muốn.
Tilo

42

Hiện có 4 toán tử nhận biết null

?? cung cấp giá trị mặc định nếu chủ đề là rỗng

return subject ?? "defaultIfNull";

?? = đặt chủ đề thành mặc định chỉ khi chủ đề là rỗng

Điều này tương tự như ?? nhưng đặt biến chủ đề thành giá trị mặc định nếu nó là giá trị rỗng.

subject ??= "defaultIfNull";

? tránh một ngoại lệ nếu chủ đề là null khi truy cập thuộc tính của chủ thể

object?.xsẽ trả về null nếu đối tượng là null, object.xsẽ gây ra một ngoại lệ nếu đối tượng là null

...? từ một tập hợp rải rác, tránh một mục rỗng trong danh sách cuối cùng nếu danh sách chủ đề là rỗng

kết quả của những điều sau đây

[
  ...[1, 2],
  null,
]

[1, 2, null]

để tránh sử dụng giá trị null ...?

var resultingList = [
  ...[1, 2],
  ...?subjectList,
];

2
Nhận xét quan trọng về việc sử dụng ?. : nếu tham chiếu nullable acó phương thức void method(), thì cú pháp sau a?.method();sẽ chỉ thực thi phương thức nếu akhông phải là null.
Alex Semeniuk

@AlexSemeniuk, điểm tuyệt vời! nhưng có cách nào để làm như thế này không?
Yo Apps

@YoApps Tôi đã hiểu rõ rằng bạn có muốn thực thi một phương thức không phải là một phần của chữ ký lớp không? Không thể thực hiện bằng bất kỳ ngôn ngữ OOP nào mà tôi biết.
Alex Semeniuk

@AlexSemeniuk vâng, tôi cũng đã thử, không hoạt động nên hoàn nguyên về cũif(a!=null){XYZ();}
Yo Apps

1
@YoApps. Ồ, ý bạn là mã này. Không, điều đó là không thể trong Dart.
Alex Semeniuk

14

Đăng phần sau, vì tôi đã kết thúc ở đây bằng cách tìm kiếm tiêu đề.

Theo https://github.com/dart-lang/sdk/issues/66 , có vẻ như câu trả lời cho "Thành ngữ kiểm tra Dart null hoặc phương pháp hay nhất là gì?" Là:

Không có thành ngữ kiểm tra null hoặc phương pháp hay nhất trong trường hợp chung. Nếu các toán tử nhận biết null không phù hợp với trường hợp của bạn, hãy sử dụng so sánh trực tiếp như trong if (object == null)hoặc if (object != null).


1
họ có optionals bây giờ :-)
Oliver Dixon

0
bool ok<T>(T obj) => obj != null;
bool nul<T>(T obj) => obj == null;

Mặc dù mã này có thể trả lời câu hỏi, nhưng việc cung cấp thêm ngữ cảnh liên quan đến lý do và / hoặc cách mã này trả lời câu hỏi sẽ cải thiện giá trị lâu dài của nó. Cách trả lời . Trân trọng.
Elletlar
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.