How to create private variables in Dart?

后端 未结 4 451
夕颜
夕颜 2020-12-03 00:20

I want to create a private variable but I cannot.

Here is my code:

void main() {
  var b = new B();
  b.test         


        
相关标签:
4条回答
  • 2020-12-03 00:51

    In dart _ is used before the variable name to declare it as private. Unlike other programming languages, here private doesn't mean it is available only to the class it is in, private means it is accessible in the file it is in and not accessible to other files.

    0 讨论(0)
  • 2020-12-03 00:55

    The top answer as of now is definitely correct.

    I'll try to go into more detail in this answer.

    I'll answer the question, but lead with this: That's just not how Dart is intended to be written, partly because library-private members make it easier to define operators like ==. (Private variables of a second object couldn't be seen for the comparison.)

    Now that we've got that out of the way, I'll start out by showing you how it's meant to be done (library-private instead of class-private), and then show you how to make a variable class-private if you still really want that. Here we go.

    If one class has no business seeing variables on another class, you might ask yourself whether they really belong in the same library:

        //This should be in a separate library from main() for the reason stated in the main method below.
    
        class MyClass {
          //Library private variable
          int _val = 0;
    
          int get val => _val;
          set val(int v) => _val = (v < 0) ? _val : v;
    
          MyClass.fromVal(int val) : _val = val;
        }
    
        void main() {
          MyClass mc = MyClass.fromVal(1);
          mc.val = -1;
          print(mc.val); //1
    
          //main() MUST BE IN A SEPARATE LIBRARY TO 
          //PREVENT MODIFYING THE BACKING FIELDS LIKE:
          mc._val = 6;
          print(mc.val); //6
        }
    

    That should be good. However if you really want private class data:

    Though you technically aren't allowed to create private variables, you could emulate it using the following closure technique.

    (HOWEVER, you should CAREFULLY consider whether you really need it and whether there is a better, more Dart-like way to do what you're trying to accomplish!)

        //A "workaround" that you should THINK TWICE before using because:
        //1. The syntax is verbose.
        //2. Both closure variables and any methods needing to access
        //   the closure variables must be defined inside a base constructor.
        //3. Those methods require typedefs to ensure correct signatures.
    
        typedef int IntGetter();
        typedef void IntSetter(int value);
    
        class MyClass {
          IntGetter getVal;
          IntSetter setVal;
    
          MyClass.base() {
            //Closure variable
            int _val = 0;
    
            //Methods defined within constructor closure
            getVal = ()=>_val;
            setVal = (int v) => _val = (v < 0) ? _val : v;
          }
    
          factory MyClass.fromVal(int val) {
            MyClass result = MyClass.base();
            result.setVal(val);
            return result;
          }
        }
    
        void main() {
          MyClass mc = MyClass.fromVal(1);
          mc.setVal(-1); //Fails
          print(mc.getVal());
    
          //On the upside, you can't access _val
          //mc._val = 6; //Doesn't compile.
        }
    

    So yeah. Just be careful and try to follow the language's best-practices and you should be fine.

    EDIT

    Apparently there's a new typedef syntax that's preferred for Dart 2. If you're using Dart 2 you should use that. Or, even better, use inline function types.

    If you use the second, it will be less verbose, but the other problems remain.

    0 讨论(0)
  • 2020-12-03 00:57

    Privacy in Dart exists at the library, rather than the class level.

    If you were to put class A into a separate library file (eg, other.dart), such as:

    library other;
    
    class A {
      int _private = 0;
    
      testA() {
        print('int value: $_private');  // 0
        _private = 5;
        print('int value: $_private'); // 5
      }
    }
    

    and then import it into your main app, such as:

    import 'other.dart';
    
    void main() {
      var b = new B();
      b.testB();    
    }
    
    
    class B extends A {
      String _private;
    
      testB() {
        _private = 'Hello';
        print('String value: $_private'); // Hello
        testA();
        print('String value: $_private'); // Hello
      }
    }
    

    You get the expected output:

    String value: Hello
    int value: 0
    int value: 5
    String value: Hello
    
    0 讨论(0)
  • 2020-12-03 01:07

    From Dart documentation:

    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.

    Libraries not only provide APIs, but are a unit of privacy: identifiers that start with an underscore _ are visible only inside the library.

    A few words about libraries:

    Every Dart app is a library, even if it doesn’t use a library directive. The import and library directives can help you create a modular and shareable code base.

    You may have heard of the part directive, which allows you to split a library into multiple Dart files.

    0 讨论(0)
提交回复
热议问题