Dart 中,@protected、@immutable 和 @internal 都是元数据(metadata)使用详解

9 min read

元数据(metadata)是一种给程序中的声明添加额外信息的机制,可以用来描述类、方法、字段等声明的特点。在 Dart 中,有三种常用的元数据:@protected、@immutable 和 @internal。

  1. @protected

@protected 元数据表示一个成员是受保护的,只能在当前类及其子类中使用。被 @protected 修饰的成员,在其所属的类中可以直接访问,在子类中也可以直接访问。但是在其他类中就不能直接访问了。

示例:

class Animal {
  @protected String name;
  
  Animal(this.name);
}

class Dog extends Animal {
  Dog(String name) : super(name);
  
  void bark() {
    print('$name is barking.');
  }
}

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void meow() {
    print('$name is meowing.');
  }
}

void main() {
  var dog = Dog('Duffy');
  dog.bark(); // 输出:Duffy is barking.
  
  var cat = Cat('Fluffy');
  cat.meow(); // 输出:Fluffy is meowing.
  
  // 下面两行代码无法编译通过:
  // print(dog.name);
  // print(cat.name);
}
  1. @immutable

@immutable 元数据表示一个类是不可变的,即其所有字段都是只读的,且不能在构造函数中赋值。被 @immutable 修饰的类是一个值对象(value object),而不是一个可变的对象。

示例:

@immutable
class Point {
  final int x;
  final int y;
  
  const Point(this.x, this.y);
}

void main() {
  var p = Point(1, 2);
  print('x: ${p.x}, y: ${p.y}');
  
  // 下面两行代码无法编译通过:
  // p.x = 3;
  // p.y = 4;
}
  1. @internal

@internal 元数据表示一个成员是内部的,只能在当前包中使用。被 @internal 修饰的成员,在其他包中是无法直接访问的。通常用于限制一些内部实现细节,避免被外部暴露。

示例:

library mylib;

import 'dart:async';

@internal
Future<void> _doSomething() async {
  // do some internal work here
}

class MyClass {
  Future<void> doSomething() async {
    await _doSomething();
  }
}

以上就是 Dart 中常用的三个元数据的使用详解。这些元数据可以为代码添加一些有用的信息,以提高代码可读性和可维护性。