You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart与Swift私有属性对比:为何Dart私有属性可被外部修改?

Dart中如何实现类似Swift的私有(set)属性效果?

在Swift中,我们可以通过private(set)修饰属性,让外部仅能读取、无法修改属性值,示例代码如下:

class Person {
    private(set) var name: String
    private(set) var age: Int

    init(name: String, age: Int){
        self.name = name
        self.age = age
    }
}

var demo5 = Person(name: "Max", age: 34);

demo5.name = "Min"; // <—— 错误:Cannot assign to property: 'name' setter is inaccessible

但在Dart中,用下划线标记的私有属性_denominator,在同一个文件的main函数里却能直接修改和访问:

main() {
  final frac = Fraction(1, 7);
  frac._denominator = 9; // <—— 可正常执行
  print(frac._denominator); // <—— 输出9
}

class Fraction {
  int _numerator;
  int _denominator; //<— 标记为私有
  Fraction(this._numerator, this._denominator);

  int get numerator => _numerator;
  int get denominator {
    return _denominator;
  }
}

问题原因

Dart的下划线私有是库级私有,而非类级私有。默认单个dart文件就是一个独立库,同一个库内的所有代码(包括main函数和类)都能访问下划线开头的成员,所以会出现上述问题。

解决方案

方案1:拆分到不同库文件(推荐)

将Fraction类单独放到一个dart文件(比如fraction.dart):

// fraction.dart
class Fraction {
  int _numerator;
  int _denominator;
  Fraction(this._numerator, this._denominator);

  int get numerator => _numerator;
  int get denominator => _denominator;
  
  // 若需内部修改,可提供专用方法(可选)
  void updateDenominator(int newDenominator) {
    if (newDenominator != 0) { // 可添加校验逻辑
      _denominator = newDenominator;
    }
  }
}

在主文件(比如main.dart)导入使用:

// main.dart
import 'fraction.dart';

main() {
  final frac = Fraction(1, 7);
  // frac._denominator = 9; // 此处报错:The setter '_denominator' isn't defined for the type 'Fraction'
  print(frac.denominator); // 输出7
  frac.updateDenominator(9); // 通过内部方法修改
  print(frac.denominator); // 输出9
}

这种方式符合Dart的私有机制设计,外部文件无法访问私有成员,只能通过类提供的getter或内部方法操作。

方案2:同一文件内的约束(代码规范层面)

如果必须将代码放在同一文件,只能通过代码规范约束,避免在类外部直接操作私有成员。若属性不需要内部修改,可将私有变量设为final,彻底禁止外部和内部的修改操作:

class Fraction {
  final int _numerator;
  final int _denominator;
  Fraction(this._numerator, this._denominator);

  int get numerator => _numerator;
  int get denominator => _denominator;
}

此时main函数无法修改_denominator,但类内部也无法修改该属性。

内容的提问来源于stack exchange,提问作者multiverse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:37:31