OLD | NEW |
1 # Strong mode generic method prototype syntax | 1 # Strong mode generic method prototype syntax |
2 | 2 |
3 This is a summary of the current (as of January 2016) comment-based generic | 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. | 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 | 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 | 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 | 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. | 8 generic methods are still being evaluated for inclusion into the language. |
9 | 9 |
10 ## Declaring generic method parameters | 10 ## Declaring generic method parameters |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 Dart by writing a type followed by `/*=T*/`. So for example, `dynamic /*=T*/` | 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 | 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 | 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 | 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: | 70 mode tools, but will be interpreted as `T` by strong mode. For example: |
71 | 71 |
72 ```dart | 72 ```dart |
73 // foo is a generic method which takes a single generic method parameter S. | 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 | 74 // In strong mode, the parameter x will have type S, and the return type will |
75 // be S | 75 // be S |
76 // In normal mode, the parameter x will have type dynamic, and the return | 76 // In normal mode, the parameter x will have type dynamic, and the return |
77 // type will be dynamic. | 77 // type will be dynamic. |
78 dynamic/*=S*/ foo/*<S>*/(dynamic/*=S*/ x) { return x; } | 78 dynamic/*=S*/ foo/*<S>*/(dynamic/*=S*/ x) { return x; } |
79 ``` | 79 ``` |
80 | 80 |
81 This can be written more concisely by leaving off the `dynamic`. | 81 This can be written more concisely by leaving off the `dynamic`. |
82 | 82 |
83 ```dart | 83 ```dart |
84 /*=S*/ foo/*<S>*/(/*=S*/ x) {return x;} | 84 /*=S*/ foo/*<S>*/(/*=S*/ x) {return x;} |
85 ``` | 85 ``` |
86 | 86 |
87 You can also put a type to the left of the `/*=T/`. This type will be used | 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: | 88 for all non-strong mode tools. For example: |
89 | 89 |
90 ```dart | 90 ```dart |
91 // This method works with `int`, `double`, or `num`. The return type will | 91 // This method works with `int`, `double`, or `num`. The return type will |
92 // match the type of the parameters. | 92 // match the type of the parameters. |
93 num/*=T*/ pickAtRandom/*<T extends num>*/(num/*=T*/ x, num/*=T*/ y) { ... } | 93 num/*=T*/ pickAtRandom/*<T extends num>*/(num/*=T*/ x, num/*=T*/ y) { ... } |
94 ``` | 94 ``` |
95 | 95 |
96 | 96 |
97 Note that the generic parameter is in scope in the return type of the function, | 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 | 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`. | 99 declaring local variables and parameters, you can also use the `/*=T*/` syntax w
ith `var`. |
100 | 100 |
101 ```dart | 101 ```dart |
102 // foo is a generic method that takes a single generic parameter S, and a value | 102 // foo is a generic method that takes a single generic parameter S, and a value |
103 // x of type S | 103 // x of type S |
104 void foo/*<S>*/(var /*=S*/ x) { | 104 void foo/*<S>*/(var /*=S*/ x) { |
105 // In strong mode, y will also have type S | 105 // In strong mode, y will also have type S |
106 var /*=S*/ y = x; | 106 var /*=S*/ y = x; |
107 | 107 |
108 // In strong mode, z will also have type S | 108 // In strong mode, z will also have type S |
109 dynamic /*=S*/ z = y; | 109 dynamic /*=S*/ z = y; |
110 } | 110 } |
111 ``` | 111 ``` |
112 | 112 |
113 Anywhere that a type literal is expected, you can also use the `/*=T*/` syntax t
o | 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. | 114 produce a type literal from the generic method parameter. |
115 | 115 |
(...skipping 12 matching lines...) Expand all Loading... |
128 You can use generic method parameters to instantiate generic classes using the | 128 You can use generic method parameters to instantiate generic classes using the |
129 same `/*=T*/` syntax. | 129 same `/*=T*/` syntax. |
130 | 130 |
131 ```dart | 131 ```dart |
132 // foo is a generic method which returns a List<S> in strong mode, | 132 // foo is a generic method which returns a List<S> in strong mode, |
133 // but which returns List<dynamic> in normal mode. | 133 // but which returns List<dynamic> in normal mode. |
134 List<dynamic /*=S*/> foo/*<S>*/(/*=S*/ x) { | 134 List<dynamic /*=S*/> foo/*<S>*/(/*=S*/ x) { |
135 // l0 is a list literal whose reified type will be List<S> in strong mode, | 135 // l0 is a list literal whose reified type will be List<S> in strong mode, |
136 // and List<dynamic> in normal mode. | 136 // and List<dynamic> in normal mode. |
137 var l0 = <dynamic /*=S*/>[x]; | 137 var l0 = <dynamic /*=S*/>[x]; |
138 | 138 |
139 // as above, but with a regular constructor. | 139 // as above, but with a regular constructor. |
140 var l1 = new List<dynamic /*=S*/>(); | 140 var l1 = new List<dynamic /*=S*/>(); |
141 return l1; | 141 return l1; |
142 } | 142 } |
143 ``` | 143 ``` |
144 | 144 |
145 In most cases, the entire type argument list to the generic class can be | 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`. | 146 enclosed in parentheses, eliminating the need for explicitly writing `dynamic`. |
147 | 147 |
148 ```dart | 148 ```dart |
149 // This is another way of writing the same code as above | 149 // This is another way of writing the same code as above |
150 List/*<S>*/ foo/*<S>*/(/*=S*/ x) { | 150 List/*<S>*/ foo/*<S>*/(/*=S*/ x) { |
151 // The shorthand syntax is not yet supported for list and map literals | 151 // The shorthand syntax is not yet supported for list and map literals |
152 var l0 = <dynamic /*=S*/>[x]; | 152 var l0 = <dynamic /*=S*/>[x]; |
153 | 153 |
154 // but with regular constructors you can use it | 154 // but with regular constructors you can use it |
155 var l1 = new List/*<S>*/(); | 155 var l1 = new List/*<S>*/(); |
156 return l1; | 156 return l1; |
157 } | 157 } |
158 ``` | 158 ``` |
159 | 159 |
160 ## Instantiating generic methods | 160 ## Instantiating generic methods |
161 | 161 |
162 Generic methods can be called without passing type arguments. Strong mode will | 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, | 163 attempt to infer the type arguments automatically. If it is unable to do so, |
(...skipping 27 matching lines...) Expand all Loading... |
191 C c = new C(); | 191 C c = new C(); |
192 // This line will produce a type error, because strong mode will infer | 192 // This line will produce a type error, because strong mode will infer |
193 // `int` as the generic argument to fill in for S | 193 // `int` as the generic argument to fill in for S |
194 String x = c.inferableFromArgument(3); | 194 String x = c.inferableFromArgument(3); |
195 | 195 |
196 // This line will produce a type error in strong mode, because `int` is | 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 | 197 // explicitly passed in as the argument to use for S |
198 String y = c.notInferable/*<int>*/(3); | 198 String y = c.notInferable/*<int>*/(3); |
199 } | 199 } |
200 ``` | 200 ``` |
OLD | NEW |