Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create private variables in Dart?

Tags:

dart

People also ask

How do you define a private Dart?

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.

How do you declare a variable in darts?

How to Declare Variable in Dart. We need to declare a variable before using it in a program. In Dart, The var keyword is used to declare a variable. The Dart compiler automatically knows the type of data based on the assigned to the variable because Dart is an infer type language.

Which variable is private variable?

In general, private variables are those variables that can be visible and accessible only within the class they belong to and not outside the class or any other class. These variables are used to access the values whenever the program runs that is used to keep the data hidden from other classes.


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.


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

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.


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.