Dart封装 – 私有数据

huangapple go评论62阅读模式
英文:

Dart Encapsulation - private data

问题

我知道我可以通过在其名称前加下划线(_)来创建一个私有属性。

但是,如果我将类和主函数放在同一个文件中,我可以访问私有属性。

class User {
  late String email;
  late String _password;

  User({required String email, required String password})
      : email = email,
        _password = password;
}

void main() {
  User u = User(email: 'myemail@gmail.com', password: 'mypassword');
  print(u._password); // 我可以访问这个私有属性
}

如果我将User类移到一个单独的文件中,一切都按预期工作,而且我无法访问私有属性。

import 'user.dart';
void main() {
  User u = User(email: 'myemail@gmail.com', password: 'mypassword');
  print(u._password); // 我无法访问这个私有属性
}

我不理解原因。

英文:

I know i can create a private property by prefixing its name with an underscore (_).

but if I put the class and the main function in the same file I can access to private properties

class User {
  late String email;
  late String _password;

  User({required String email, required String password})
      : email = email,
        _password = password;
}

void main() {
  User u = User(email: 'myemail@gmail.com', password: 'mypassword');
  print(u._password); // I can access to this private property
}

if I move the User class to a separate file everything works like expected, and i can't access private properties

import 'user.dart';
void main() {
  User u = User(email: 'myemail@gmail.com', password: 'mypassword');
  print(u._password); // I can't access to this private property
}

I didn't understand the reason.

答案1

得分: 2

与Java不同,Dart没有关键字public、protected和private。如果一个标识符以下划线(_)开头,它对其是私有的。

所以基本上下划线并不使"变量私有",就像我们从Java或C#等语言中习惯的那样,而是使其对私有(粗略地说,这与Java的包(package)是相同的)。

这就是为什么如果你在user.dart文件中放置指令part of 'main.dart';,并在main.dart文件中放置指令part 'user.dart';,你将能够访问私有字段,即使类位于不同的文件中。part ofpart 指令将两个文件视为相同的


如果你好奇为什么Dart使用下划线而不是像public或private这样的访问修饰符关键字,可以查看SDK问题#33383 https://github.com/dart-lang/sdk/issues/33383

简而言之,从我理解的角度来看:由于Dart语言支持动态成员访问,使用库级别的可见性比基于类的可见性更具性能,正如@eernstg所说:

我认为重要的是要注意,这实际上不是关于语法。你可以选择许多不同的语法形式来表示相同的东西,但关键是底层结构

英文:

> Unlike Java, Dart doesn’t have the keywords public, protected, and private. If an identifier starts with an underscore (_), it's private to its library.
>
> https://dart.dev/guides/language/language-tour#important-concepts.

So basically the underscore does not make "variable private" the way we are used to (from languages like Java or C#) but it makes private to the library (which, roughly saying, is the same as a Java package).

That's why if you put the directive part of 'main.dart'; in the user.dart and the directive part 'user.dart'; in the main.dart file you will be able to access the private field, even the class being in a different file. The part of and part directives makes two files the same library.


If you are curious why Dart uses underscores instead of access modifier keywords like public or private, see SDK issue #33383 https://github.com/dart-lang/sdk/issues/33383.

In a nutshell, from what I have understood: since the Dart language supports dynamic member access, it's far more performant use library level visibility than class-based visibility, as @eernstg said:

> I think it's important to note that this is actually not about syntax. You could choose lots of different syntactic forms for the same thing, but it's the underlying structure that matters.

答案2

得分: 0

如果你想访问一个类中的变量,请使用这个。

```dart
class User {
  late String email;
  late String _password;

  User({required String email, required String password})
      : email = email,
        _password = password;

  // 这被称为一个获取函数,你可以从类实例中调用它。
  String get getUserPassword => _password;
}
import 'user.dart';
void main() {
  User u = User(email: 'myemail@gmail.com', password: 'mypassword');
  print(u.getUserPassword); // 在这里做出更改
}

愉快的编程!


<details>
<summary>英文:</summary>

If you want to access a variable from a class, use this

class User {
late String email;
late String _password;

User({required String email, required String password})
: email = email,
_password = password;

//this is called a get function, which you can call from class instance.
String get getUserPassword => _password;
}


import 'user.dart';
void main() {
User u = User(email: 'myemail@gmail.com', password: 'mypassword');
print(u.getUserPassword); // changes here
}


Happy coding!!

</details>



huangapple
  • 本文由 发表于 2023年2月6日 21:19:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75361840.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定