Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: GENERIC_METHODS.md

Issue 1541833002: Update strong mode doc (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Fixed links Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | STRONG_MODE.md » ('j') | STRONG_MODE.md » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Strong mode generic method prototype syntax
2
3 This is a summary of the current (as of January 2016) comment-based generic
4 method syntax supported by the analyzer strong mode and the Dart Dev Compiler.
5 The comment-based syntax essentially uses the proposed actual generic method
6 syntax, but wraps it in comments. This allows developers to experiment with
7 generic methods while still ensuring that their code runs on all platforms while
8 generic methods are still being evaluated for inclusion into the language.
9
10 ## Declaring generic method parameters
11
12 Generic method parameters are listed using a block comment after the method or
13 function name, inside of angle brackets.
14
15 ```dart
16 // This declares a function which takes two unused generic method parameters
17 int f/*<S, T>*/(int x) => 3;
18 ```
19
20 As with classes, you can put bounds on type parameters.
21
22 ```dart
23 // This declares a function which takes two unused generic method parameters
24 // The first parameter (S) must extend num
25 // The second parameter (T) must extend List<S>
26 int f/*<S extends num, T extends List<S>>*/(int x) => 3;
27 ```
28
29 Class methods (instance and static) can be declared to take generic parameters
30 in the same way.
31
32 ```dart
33 class C {
34 static int f/*<S, T>*/(int x) => 3;
35 int m/*<S, T>*/(int x) => 3;
36 }
37 ```
38
39 Function typed parameters, local functions, and function expressions can also be
40 declared to take generic parameters.
41
42 ```dart
43 // foo takes a generic method as a parameter
44 void foo(int f/*<S>*/(int x)) {}
45
46 // foo declares a local generic function
47 void foo() {
48 int f/*<S>*/(int x) => 3;
49 return;
50 }
51
52 // foo binds a generic function expression to a local variable.
53 void foo() {
54 var x = /*<S>*/(int x) => x;
55 }
56 ```
57
58 We do not currently support a way to declare a function as returning a generic
59 function. This will eventually be supported using something analogous to Dart
60 typedefs.
61
62 ## Using generic method parameters
63
64 The previous examples declared generic method parameters, but did not use them.
65 You can use a generic method parameter `T` anywhere that a type is expected in
66 Dart by writing a type followed by `/*=T*/`. So for example, `dynamic /*=T*/`
67 will be interpreted as `dynamic` by all non-strong mode tools, but will be
68 interpreted as `T` by strong mode. In places where it is valid to leave off a
69 type, simply writing `/*=T*/` will be interpreted as `dynamic` by non-strong
70 mode tools, but will be interpreted as `T` by strong mode. For example:
71
72 ```dart
73 // foo is a generic method which takes a single generic method parameter S.
74 // In strong mode, the parameter x will have type S, and the return type will
75 // be S
76 // In normal mode, the parameter x will have type dynamic, and the return
77 // type will be dynamic.
78 dynamic/*=S*/ foo/*<S>*/(dynamic/*=S*/ x) { return x; }
79 ```
80
81 This can be written more concisely by leaving off the `dynamic`.
82
83 ```dart
84 /*=S*/ foo/*<S>*/(/*=S*/ x) {return x;}
85 ```
86
87 You can also put a type to the left of the `/*=T/`. This type will be used
88 for all non-strong mode tools. For example:
89
90 ```dart
91 // This method works with `int`, `double`, or `num`. The return type will
92 // match the type of the parameters.
93 num/*=T*/ pickAtRandom/*<T extends num>*/(num/*=T*/ x, num/*=T*/ y) { ... }
94 ```
95
96
97 Note that the generic parameter is in scope in the return type of the function,
98 in the argument list of the function, and in the body of the function. When
99 declaring local variables and parameters, you can also use the `/*=T*/` syntax w ith `var`.
100
101 ```dart
102 // foo is a generic method that takes a single generic parameter S, and a value
103 // x of type S
104 void foo/*<S>*/(var /*=S*/ x) {
105 // In strong mode, y will also have type S
106 var /*=S*/ y = x;
107
108 // In strong mode, z will also have type S
109 dynamic /*=S*/ z = y;
110 }
111 ```
112
113 Anywhere that a type literal is expected, you can also use the `/*=T*/` syntax t o
114 produce a type literal from the generic method parameter.
115
116 ```dart
117 void foo/*<S>*/(/*=S*/ x) {
118 // In strong mode, s will get the type literal for S
119 Type s = dynamic /*=S*/;
120
121 // In strong mode, this attempts to cast 3 as type S
122 var y = (3 as dynamic /*=S*/);
123 }
124 ```
125
126 ## Instantiating generic classes with generic method parameters
127
128 You can use generic method parameters to instantiate generic classes using the
129 same `/*=T*/` syntax.
130
131 ```dart
132 // foo is a generic method which returns a List<S> in strong mode,
133 // but which returns List<dynamic> in normal mode.
134 List<dynamic /*=S*/> foo/*<S>*/(/*=S*/ x) {
135 // l0 is a list literal whose reified type will be List<S> in strong mode,
136 // and List<dynamic> in normal mode.
137 var l0 = <dynamic /*=S*/>[x];
138
139 // as above, but with a regular constructor.
140 var l1 = new List<dynamic /*=S*/>();
141 return l1;
142 }
143 ```
144
145 In most cases, the entire type argument list to the generic class can be
146 enclosed in parentheses, eliminating the need for explicitly writing `dynamic`.
147
148 ```dart
149 // This is another way of writing the same code as above
150 List/*<S>*/ foo/*<S>*/(/*=S*/ x) {
151 // The shorthand syntax is not yet supported for list and map literals
152 var l0 = <dynamic /*=S*/>[x];
153
154 // but with regular constructors you can use it
155 var l1 = new List/*<S>*/();
156 return l1;
157 }
158 ```
159
160 ## Instantiating generic methods
161
162 Generic methods can be called without passing type arguments. Strong mode will
163 attempt to infer the type arguments automatically. If it is unable to do so,
164 then the type arguments will be filled in with whatever their declared bounds
165 are (by default, `dynamic`).
166
167 ```dart
168 class C {
169 /*=S*/ inferableFromArgument/*<S>*/(/*=S*/ x) { return null;}
170 /*=S*/ notInferable/*<S>*/(int x) { return null;}
171 }
172
173 void main() {
174 C c = new C();
175 // This line will produce a type error, because strong mode will infer
176 // `int` as the generic argument to fill in for S
177 String x = c.inferableFromArgument(3);
178
179 // This line will not produce a type error, because strong mode is unable
180 // to infer a type and will fill in the type argument with `dynamic`.
181 String y = c.notInferable(3);
182 }
183 ```
184
185 In the case that strong mode cannot infer the generic type arguments, the same
186 syntax that was shown above for instantiating generic classes can be used to
187 instantiate generic methods explicitly.
188
189 ```dart
190 void main() {
191 C c = new C();
192 // This line will produce a type error, because strong mode will infer
193 // `int` as the generic argument to fill in for S
194 String x = c.inferableFromArgument(3);
195
196 // This line will produce a type error in strong mode, because `int` is
197 // explicitly passed in as the argument to use for S
198 String y = c.notInferable/*<int>*/(3);
199 }
200 ```
OLDNEW
« no previous file with comments | « no previous file | STRONG_MODE.md » ('j') | STRONG_MODE.md » ('J')

Powered by Google App Engine
This is Rietveld 408576698