Generics trong Dart
1. Giới thiệu
Generics cho phép viết code linh hoạt, tái sử dụng với nhiều kiểu dữ liệu khác nhau.
2. Generic Class
class Box<T> {
T value;
Box(this.value);
T getValue() => value;
void setValue(T newValue) => value = newValue;
}
void main() {
var intBox = Box<int>(42);
var stringBox = Box<String>('Hello');
print(intBox.getValue()); // 42
print(stringBox.getValue()); // Hello
}3. Generic Function
T first<T>(List<T> items) {
return items[0];
}
void main() {
print(first<int>([1, 2, 3])); // 1
print(first<String>(['a', 'b'])); // a
// Type inference
print(first([1, 2, 3])); // 1
}4. Nhiều Type Parameters
class Pair<K, V> {
K key;
V value;
Pair(this.key, this.value);
@override
String toString() => '($key, $value)';
}
void main() {
var pair = Pair<String, int>('age', 25);
print(pair); // (age, 25)
}5. Generic với extends (Bounded)
class NumberBox<T extends num> {
T value;
NumberBox(this.value);
T add(T other) => (value + other) as T;
}
void main() {
var intBox = NumberBox(10);
print(intBox.add(5)); // 15
var doubleBox = NumberBox(3.14);
print(doubleBox.add(2.86)); // 6.0
// var stringBox = NumberBox('hello'); // Error!
}6. Generic Collections
void main() {
// List<T>
List<int> numbers = [1, 2, 3];
// Map<K, V>
Map<String, int> ages = {'Alice': 25, 'Bob': 30};
// Set<T>
Set<String> unique = {'a', 'b', 'c'};
}7. Generic Interface
abstract class Repository<T> {
T? findById(int id);
List<T> findAll();
void save(T item);
void delete(int id);
}
class UserRepository implements Repository<User> {
final Map<int, User> _users = {};
@override
User? findById(int id) => _users[id];
@override
List<User> findAll() => _users.values.toList();
@override
void save(User item) => _users[item.id] = item;
@override
void delete(int id) => _users.remove(id);
}8. Covariant và Contravariant
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
// Covariant: List<Dog> là subtype của List<Animal>
void printAnimals(List<Animal> animals) {
for (var animal in animals) {
print(animal);
}
}
void main() {
List<Dog> dogs = [Dog(), Dog()];
printAnimals(dogs); // OK
}9. Factory với Generics
class Cache<T> {
final Map<String, T> _cache = {};
T? get(String key) => _cache[key];
void set(String key, T value) => _cache[key] = value;
void clear() => _cache.clear();
}
void main() {
var userCache = Cache<User>();
var configCache = Cache<String>();
}📝 Tóm tắt
- Generic type parameter
extendsgiới hạn type- Nhiều params:
<K, V> - Giúp code type-safe và tái sử dụng
- Phổ biến trong collections và repositories
Last updated on