softshipper
softshipper

Reputation: 34071

confusing about generics

I try to understand Dart generics. When I code my own custom generics class, then I understand how generics works, like

class Class1<T> {

    T func1(T para1, T para2) {
        return para1 = para2;
    }
}

main() {
    var mycl = new Class1<int>();
    print(mycl.func1(3, 5));
}

I know, it is very simple example and maybe this does not make sense, but anyway, I know approximately how to use generics.

But now, what is my problem, look at this code

StreamSubscription<T> listen(Function void onData(T event), {Function onError, Function void onDone(), bool cancelOnError}) 

I copied this from HttpServer API and is the listen method. My question is, does Dart support generics method? I was searching in web about Dart generics method and could not find it.

I am really try to understand, how to read Dart API docu, but sometimes it is so difficult to understand.

Upvotes: 2

Views: 1512

Answers (2)

lrn
lrn

Reputation: 71623

Dart does not support generic methods.

What you are seeing here is a method that is part of a generic class. The T type variables comes from the class class Stream<T>.

The method:

StreamSubscription<T> listen(Function void onData(T event), {Function onError, Function void onDone(), bool cancelOnError})

means that on a Stream<int>, the listen method returns a StreamSubscription<int>, and it expects an onData function that takes int arguments.

Example:

class Gift<T> {
  T _content;
  Gift(T content) : _content = _content;
  Gift<Gift<T>> wrap() => new Gift<Gift<T>>(this);
  T unwrap() => _content;
  T replace(T replacement(T current)) { 
    var old = _content; 
    _content = replacement(old);
    return old; 
  }
}

The function wrap isn't "generic". It returns a new type based on the type of the current object. The return type contains T, but it is the same T as the instance of the Gift the method is called on.

The function replace takes a parameter of type T -> T. The method is not "generic", it just has a type that depends on the type of T in the Gift instance it is called one.

That is, the methods are not generic in the sense that they can be parameterized with a new Type parameter every time they are called. Instead the Gift class is generic, and each instance of Gift has a value of the type parameter. The methods on such an instance can use that type parameter in their signatures, but for one Gift instance, the types are always the same. A Gift<int> will have a wrap method the returns Gift<Gift<int>>, and the replace method expects an argument of type int -> int.

Upvotes: 5

JAre
JAre

Reputation: 4756

Dart doesn't really need them. Types are optional, you can drop them and use "duck typing".

void main() {
  returnNthElement(int index, var something){
    return something[index];
  }
   print(returnNthElement(1, [1,2,3,4,5])); //2
   print(returnNthElement(1, "HELLO"));// E 
   print(returnNthElement(1, 100));//NoSuchMethodError: method not found: '[]'
}

But since generic type persist at the runtime you can use them like this:

void main() {
  foo(List l){
    if (l is List<int>) return "$l is list of ints";
    if (l is List<String>) return "$l is list of Strings";
  }
   var li = new List<int>();
   li.addAll([1,2,3,4,5]);
   var ls = new List<String>();
   ls.addAll(["HELLO", "DART"]);
   print(foo(li)); //[1, 2, 3, 4, 5] is list of ints
   print(foo(ls)); //[HELLO, DART] is list of Strings
}

Upvotes: 0

Related Questions