Chuyển đến nội dung chính

Bài đăng

Hiển thị các bài đăng có nhãn Ngôn ngữ

Record và pattern trong Dart: chúng thay thế những gì

Trước khi có record, trả về hai giá trị từ một hàm nghĩa là chọn một trong ba lựa chọn đều không hấp dẫn: một class chỉ dùng một lần, một List<Object> mà bạn phải truy cập theo chỉ số, hoặc hai tham số ra thông qua một lớp bọc. Record biến nó thành một dòng. ({ int width, int height}) measure ( String text) { // ... return (width : 120 , height : 40 ); } final size = measure ( 'hello' ); print (size.width); Đó là tính năng nổi bật nhất, và nó là phần nhỏ nhất trong những gì record cùng pattern đã thay đổi. Record: theo cấu trúc, không theo tên Kiểu của một record chính là hình dạng của nó. (int, String) và (int, String) là cùng một kiểu bất kể chúng được tạo ở đâu, và đó là điểm phân biệt record với class. // Theo vị trí ( String , int ) parseEntry ( String line) { final parts = line. split ( ':' ); return (parts[ 0 ], int . parse (parts[ 1 ])); } // Có tên — rõ ràng hơn ở nơi gọi ({ String name, int score}) parseNamed ( ...

Extension type trong Dart: một cái tên mới cho giá trị cũ

Mọi codebase vượt qua một kích thước nhất định đều dính lỗi này ít nhất một lần: void transfer ( String fromUserId, String toAccountId, int cents) { ... } transfer (accountId, userId, 500 ); // biên dịch ngon lành, sai lúc chạy Cả hai đều là String , nên hệ thống kiểu không có gì để nói. Cách sửa thường thấy là một class bọc, và nó tốn một lần cấp phát cho mỗi ID bạn chạm vào. Extension type là đúng cách sửa đó nhưng không cấp phát. extension type UserId ( String value) {} extension type AccountId ( String value) {} void transfer ( UserId from, AccountId to, int cents) { ... } transfer (accountId, userId, 500 ); // lỗi biên dịch Lúc chạy, UserId chính là một String . Không có đối tượng bọc, không có truy cập trường gián tiếp, không cấp phát gì cả. Sự phân biệt chỉ tồn tại trong hệ thống kiểu tĩnh, và bị xoá đi trước khi chương trình chạy. ”Bị xoá” thật sự nghĩa là gì Đây là phần quyết định extension type có hợp với bài toán của bạn hay không. Trình biên dịch ...

Record và pattern trong Dart: chúng thay thế những gì

Trước khi có record, trả về hai giá trị từ một hàm nghĩa là chọn một trong ba lựa chọn đều không hấp dẫn: một class chỉ dùng một lần, một List<Object> mà bạn phải truy cập theo chỉ số, hoặc hai tham số ra thông qua một lớp bọc. Record biến nó thành một dòng. ({ int width, int height}) measure ( String text) { // ... return (width : 120 , height : 40 ); } final size = measure ( 'hello' ); print (size.width); Đó là tính năng nổi bật nhất, và nó là phần nhỏ nhất trong những gì record cùng pattern đã thay đổi. Record: theo cấu trúc, không theo tên Kiểu của một record chính là hình dạng của nó. (int, String) và (int, String) là cùng một kiểu bất kể chúng được tạo ở đâu, và đó là điểm phân biệt record với class. // Theo vị trí ( String , int ) parseEntry ( String line) { final parts = line. split ( ':' ); return (parts[ 0 ], int . parse (parts[ 1 ])); } // Có tên — rõ ràng hơn ở nơi gọi ({ String name, int score}) parseNamed ( ...

Extension type trong Dart: một cái tên mới cho giá trị cũ

Mọi codebase vượt qua một kích thước nhất định đều dính lỗi này ít nhất một lần: void transfer ( String fromUserId, String toAccountId, int cents) { ... } transfer (accountId, userId, 500 ); // biên dịch ngon lành, sai lúc chạy Cả hai đều là String , nên hệ thống kiểu không có gì để nói. Cách sửa thường thấy là một class bọc, và nó tốn một lần cấp phát cho mỗi ID bạn chạm vào. Extension type là đúng cách sửa đó nhưng không cấp phát. extension type UserId ( String value) {} extension type AccountId ( String value) {} void transfer ( UserId from, AccountId to, int cents) { ... } transfer (accountId, userId, 500 ); // lỗi biên dịch Lúc chạy, UserId chính là một String . Không có đối tượng bọc, không có truy cập trường gián tiếp, không cấp phát gì cả. Sự phân biệt chỉ tồn tại trong hệ thống kiểu tĩnh, và bị xoá đi trước khi chương trình chạy. ”Bị xoá” thật sự nghĩa là gì Đây là phần quyết định extension type có hợp với bài toán của bạn hay không. Trình biên dịch ...

Primary constructor trong Dart 3.13: bớt boilerplate, một thay đổi phá vỡ thật sự

Dart 3.13 ra cùng Flutter 3.47, và tính năng tiêu điểm là thứ lập trình viên Dart đòi từ hồi ngôn ngữ có null safety: primary constructor đã stable . Khai báo field và constructor ngay trên header của class, và xoá đi ba dòng nghi thức mà mọi class model trong codebase của bạn đang lặp lại. Trong bản phát hành cũng có một thay đổi phá vỡ ẩn mình, và nó không phải thứ phần lớn mọi người đoán. Hình dạng cơ bản Dạng truyền thống: class Point { int x; int y; Point ( this .x, this .y); } Dạng primary constructor: class Point ( var int x, var int y); Đó là toàn bộ class. Chú ý thứ tự — modifier đứng trước, rồi tới kiểu, rồi tới tên: var int x , không phải int var x . Declaring parameter mới là tính năng thật Đây là phần đáng hiểu cho kỹ, vì thiết kế ở đây tinh tế hơn câu “cú pháp ngắn hơn”. Một tham số có tiền tố var hoặc final là declaring parameter : nó sinh ra một instance field. Tham số không có modifier nào hành xử như một đối số constructor thông thường v...