Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package reflect | 5 package reflect |
6 | 6 |
7 import ( | 7 import ( |
8 "math" | 8 "math" |
9 "runtime" | 9 "runtime" |
10 "unsafe" | 10 "unsafe" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 // Value is the reflection interface to a Go value. | 44 // Value is the reflection interface to a Go value. |
45 // | 45 // |
46 // Not all methods apply to all kinds of values. Restrictions, | 46 // Not all methods apply to all kinds of values. Restrictions, |
47 // if any, are noted in the documentation for each method. | 47 // if any, are noted in the documentation for each method. |
48 // Use the Kind method to find out the kind of value before | 48 // Use the Kind method to find out the kind of value before |
49 // calling kind-specific methods. Calling a method | 49 // calling kind-specific methods. Calling a method |
50 // inappropriate to the kind of type causes a run time panic. | 50 // inappropriate to the kind of type causes a run time panic. |
51 // | 51 // |
52 // The zero Value represents no value. | 52 // The zero Value represents no value. |
53 // Its IsValid method returns false, its Kind method returns Invalid, | 53 // Its IsValid method returns false, its Kind method returns Invalid, |
54 // its String method returns "<invalid Value>", and all other methods panic. | 54 // its String method returns "<invalid Value>", and all other methods panic. |
niemeyer
2011/04/04 13:52:35
The usage of the zero value Value{} as meaning som
rsc
2011/04/05 16:29:45
Suggest a better name?
| |
55 // Most functions and methods never return an invalid value. | 55 // Most functions and methods never return an invalid value. |
56 // If one does, its documentation states the conditions explicitly. | 56 // If one does, its documentation states the conditions explicitly. |
57 type Value struct { | 57 type Value struct { |
58 Internal valueInterface | 58 Internal valueInterface |
r
2011/04/02 18:45:33
why is Internal exported?
niemeyer
2011/04/04 13:52:35
Likely to allow the use of Value{}, but indeed it
rog
2011/04/04 17:06:50
we don't allow passing external structs with unexp
| |
59 } | 59 } |
60 | 60 |
61 // TODO(rsc): This implementation of Value is a just a façade | 61 // TODO(rsc): This implementation of Value is a just a façade |
62 // in front of the old implementation, now called valueInterface. | 62 // in front of the old implementation, now called valueInterface. |
63 // A future CL will change it to a real implementation. | 63 // A future CL will change it to a real implementation. |
64 // Changing the API is already a big enough step for one CL. | 64 // Changing the API is already a big enough step for one CL. |
65 | 65 |
66 // A ValueError occurs when a Value method is invoked on | 66 // A ValueError occurs when a Value method is invoked on |
67 // a Value that does not support it. Such cases are documented | 67 // a Value that does not support it. Such cases are documented |
68 // in the description of each method. | 68 // in the description of each method. |
(...skipping 21 matching lines...) Expand all Loading... | |
90 } | 90 } |
91 | 91 |
92 func (v Value) internal() valueInterface { | 92 func (v Value) internal() valueInterface { |
93 vi := v.Internal | 93 vi := v.Internal |
94 if vi == nil { | 94 if vi == nil { |
95 panic(&ValueError{methodName(), 0}) | 95 panic(&ValueError{methodName(), 0}) |
96 } | 96 } |
97 return vi | 97 return vi |
98 } | 98 } |
99 | 99 |
100 func (v Value) kindPanic(want Kind) valueInterface { | 100 func (v Value) panicIfNot(want Kind) valueInterface { |
r
2011/04/02 18:45:33
this name reads poorly when used. i'd called it pa
| |
101 vi := v.Internal | 101 vi := v.Internal |
102 if vi == nil { | 102 if vi == nil { |
103 panic(&ValueError{methodName(), 0}) | 103 panic(&ValueError{methodName(), 0}) |
104 } | 104 } |
105 if k := vi.Kind(); k != want { | 105 if k := vi.Kind(); k != want { |
106 panic(&ValueError{methodName(), k}) | 106 panic(&ValueError{methodName(), k}) |
107 } | 107 } |
108 return vi | 108 return vi |
109 } | 109 } |
110 | 110 |
111 func (v Value) kindsPanic(wants []Kind) valueInterface { | 111 func (v Value) panicIfNots(wants []Kind) valueInterface { |
r
2011/04/02 18:45:33
ditto
| |
112 vi := v.Internal | 112 vi := v.Internal |
113 if vi == nil { | 113 if vi == nil { |
114 panic(&ValueError{methodName(), 0}) | 114 panic(&ValueError{methodName(), 0}) |
115 } | 115 } |
116 k := vi.Kind() | 116 k := vi.Kind() |
117 for _, want := range wants { | 117 for _, want := range wants { |
118 if k == want { | 118 if k == want { |
119 return vi | 119 return vi |
120 } | 120 } |
121 } | 121 } |
122 panic(&ValueError{methodName(), k}) | 122 panic(&ValueError{methodName(), k}) |
123 } | 123 } |
124 | 124 |
125 // Addr returns a pointer value representing the address of v. | 125 // Addr returns a pointer value representing the address of v. |
126 // It panics if CanAddr() returns false. | 126 // It panics if CanAddr() returns false. |
127 // Addr is typically used to obtain a pointer to a struct field | 127 // Addr is typically used to obtain a pointer to a struct field |
128 // or slice element in order to call a method that requires a | 128 // or slice element in order to call a method that requires a |
129 // pointer receiver. | 129 // pointer receiver. |
130 func (v Value) Addr() Value { | 130 func (v Value) Addr() Value { |
131 return v.internal().Addr() | 131 return v.internal().Addr() |
132 } | 132 } |
133 | 133 |
134 // Bool returns v's underlying value. | 134 // Bool returns v's underlying value. |
135 // It panics if v's kind is not Bool. | 135 // It panics if v's kind is not Bool. |
136 func (v Value) Bool() bool { | 136 func (v Value) Bool() bool { |
137 » u := v.kindPanic(Bool).(*boolValue) | 137 » u := v.panicIfNot(Bool).(*boolValue) |
138 return u.Get() | 138 return u.Get() |
139 } | 139 } |
140 | 140 |
141 // CanAddr returns true if the value's address can be obtained with Addr. | 141 // CanAddr returns true if the value's address can be obtained with Addr. |
142 // Such values are called addressable. A value is addressable if it is | 142 // Such values are called addressable. A value is addressable if it is |
143 // an element of a slice, an element of an addressable array, | 143 // an element of a slice, an element of an addressable array, |
144 // a field of an addressable struct, the result of dereferencing a pointer, | 144 // a field of an addressable struct, the result of dereferencing a pointer, |
145 // or the result of a call to NewValue, MakeChan, MakeMap, or MakeZero. | 145 // or the result of a call to NewValue, MakeChan, MakeMap, or Zero. |
146 // If CanAddr returns false, calling Addr will panic. | 146 // If CanAddr returns false, calling Addr will panic. |
147 func (v Value) CanAddr() bool { | 147 func (v Value) CanAddr() bool { |
148 return v.internal().CanAddr() | 148 return v.internal().CanAddr() |
149 } | 149 } |
150 | 150 |
151 // CanSet returns true if the value of v can be changed. | 151 // CanSet returns true if the value of v can be changed. |
152 // Values obtained by the use of unexported struct fields | 152 // Values obtained by the use of unexported struct fields |
153 // can be read but not set. | 153 // can be read but not set. |
154 // If CanSet returns false, calling Set or any type-specific | 154 // If CanSet returns false, calling Set or any type-specific |
155 // setter (e.g., SetBool, SetInt64) will panic. | 155 // setter (e.g., SetBool, SetInt64) will panic. |
156 func (v Value) CanSet() bool { | 156 func (v Value) CanSet() bool { |
niemeyer
2011/04/04 13:52:35
Can we have a CanBeNil() or similar in the same sp
rog
2011/04/04 17:06:50
an alternative might be to have IsNil return false
rsc
2011/04/05 16:29:45
I think by "usual trick" you mean testing for the
| |
157 return v.internal().CanSet() | 157 return v.internal().CanSet() |
158 } | 158 } |
159 | 159 |
160 // Call calls the function v with the input parameters in. | 160 // Call calls the function v with the input parameters in. |
161 // It panics if v's Kind is not Func. | 161 // It panics if v's Kind is not Func. |
162 // It returns the output parameters as Values. | 162 // It returns the output parameters as Values. |
163 func (v Value) Call(in []Value) []Value { | 163 func (v Value) Call(in []Value) []Value { |
164 » return v.kindPanic(Func).(*funcValue).Call(in) | 164 » return v.panicIfNot(Func).(*funcValue).Call(in) |
165 } | 165 } |
166 | 166 |
167 var capKinds = []Kind{Array, Chan, Slice} | 167 var capKinds = []Kind{Array, Chan, Slice} |
168 | 168 |
169 type capper interface { | 169 type capper interface { |
170 Cap() int | 170 Cap() int |
171 } | 171 } |
172 | 172 |
173 // Cap returns v's capacity. | 173 // Cap returns v's capacity. |
174 // It panics if v's Kind is not Array, Chan, or Slice. | 174 // It panics if v's Kind is not Array, Chan, or Slice. |
175 func (v Value) Cap() int { | 175 func (v Value) Cap() int { |
176 » return v.kindsPanic(capKinds).(capper).Cap() | 176 » return v.panicIfNots(capKinds).(capper).Cap() |
177 } | 177 } |
178 | 178 |
179 // Close closes the channel v. | 179 // Close closes the channel v. |
180 // It panics if v's Kind is not Chan. | 180 // It panics if v's Kind is not Chan. |
181 func (v Value) Close() { | 181 func (v Value) Close() { |
182 » v.kindPanic(Chan).(*chanValue).Close() | 182 » v.panicIfNot(Chan).(*chanValue).Close() |
183 } | 183 } |
184 | 184 |
185 var complexKinds = []Kind{Complex64, Complex128} | 185 var complexKinds = []Kind{Complex64, Complex128} |
186 | 186 |
187 // Complex returns v's underlying value, as a complex128. | 187 // Complex returns v's underlying value, as a complex128. |
188 // It panics if v's Kind is not Complex64 or Complex128 | 188 // It panics if v's Kind is not Complex64 or Complex128 |
189 func (v Value) Complex() complex128 { | 189 func (v Value) Complex() complex128 { |
190 » return v.kindsPanic(complexKinds).(*complexValue).Get() | 190 » return v.panicIfNots(complexKinds).(*complexValue).Get() |
191 } | 191 } |
192 | 192 |
193 var interfaceOrPtr = []Kind{Interface, Ptr} | 193 var interfaceOrPtr = []Kind{Interface, Ptr} |
194 | 194 |
195 type elemer interface { | 195 type elemer interface { |
196 Elem() Value | 196 Elem() Value |
197 } | 197 } |
198 | 198 |
199 // Elem returns the value that the interface v contains | 199 // Elem returns the value that the interface v contains |
200 // or that the pointer v points to. | 200 // or that the pointer v points to. |
201 // It panics if v's Kind is not Interface or Ptr. | 201 // It panics if v's Kind is not Interface or Ptr. |
202 // It returns the zero Value if v is nil. | 202 // It returns the zero Value if v is nil. |
203 func (v Value) Elem() Value { | 203 func (v Value) Elem() Value { |
204 » return v.kindsPanic(interfaceOrPtr).(elemer).Elem() | 204 » return v.panicIfNots(interfaceOrPtr).(elemer).Elem() |
205 } | 205 } |
206 | 206 |
207 // Field returns the i'th field of the struct v. | 207 // Field returns the i'th field of the struct v. |
208 // It panics if v's Kind is not Struct. | 208 // It panics if v's Kind is not Struct. |
209 func (v Value) Field(i int) Value { | 209 func (v Value) Field(i int) Value { |
210 » return v.kindPanic(Struct).(*structValue).Field(i) | 210 » return v.panicIfNot(Struct).(*structValue).Field(i) |
211 } | 211 } |
212 | 212 |
213 // FieldByIndex returns the nested field corresponding to index. | 213 // FieldByIndex returns the nested field corresponding to index. |
214 // It panics if v's Kind is not struct. | 214 // It panics if v's Kind is not struct. |
215 func (v Value) FieldByIndex(index []int) Value { | 215 func (v Value) FieldByIndex(index []int) Value { |
216 » return v.kindPanic(Struct).(*structValue).FieldByIndex(index) | 216 » return v.panicIfNot(Struct).(*structValue).FieldByIndex(index) |
217 } | 217 } |
218 | 218 |
219 // FieldByName returns the struct field with the given name. | 219 // FieldByName returns the struct field with the given name. |
220 // It returns the zero Value if no field was found. | 220 // It returns the zero Value if no field was found. |
221 // It panics if v's Kind is not struct. | 221 // It panics if v's Kind is not struct. |
222 func (v Value) FieldByName(name string) Value { | 222 func (v Value) FieldByName(name string) Value { |
223 » return v.kindPanic(Struct).(*structValue).FieldByName(name) | 223 » return v.panicIfNot(Struct).(*structValue).FieldByName(name) |
224 } | 224 } |
225 | 225 |
226 // FieldByNameFunc returns the struct field with a name | 226 // FieldByNameFunc returns the struct field with a name |
227 // that satisfies the match function. | 227 // that satisfies the match function. |
228 // It panics if v's Kind is not struct. | 228 // It panics if v's Kind is not struct. |
229 // It returns the zero Value if no field was found. | 229 // It returns the zero Value if no field was found. |
230 func (v Value) FieldByNameFunc(match func(string) bool) Value { | 230 func (v Value) FieldByNameFunc(match func(string) bool) Value { |
231 » return v.kindPanic(Struct).(*structValue).FieldByNameFunc(match) | 231 » return v.panicIfNot(Struct).(*structValue).FieldByNameFunc(match) |
232 } | 232 } |
233 | 233 |
234 var floatKinds = []Kind{Float32, Float64} | 234 var floatKinds = []Kind{Float32, Float64} |
235 | 235 |
236 // Float returns v's underlying value, as an float64. | 236 // Float returns v's underlying value, as an float64. |
237 // It panics if v's Kind is not Float32 or Float64 | 237 // It panics if v's Kind is not Float32 or Float64 |
238 func (v Value) Float() float64 { | 238 func (v Value) Float() float64 { |
239 » return v.kindsPanic(floatKinds).(*floatValue).Get() | 239 » return v.panicIfNots(floatKinds).(*floatValue).Get() |
240 } | 240 } |
241 | 241 |
242 var arrayOrSlice = []Kind{Array, Slice} | 242 var arrayOrSlice = []Kind{Array, Slice} |
243 | 243 |
244 // Index returns v's i'th element. | 244 // Index returns v's i'th element. |
245 // It panics if v's Kind is not Array or Slice. | 245 // It panics if v's Kind is not Array or Slice. |
246 func (v Value) Index(i int) Value { | 246 func (v Value) Index(i int) Value { |
247 » return v.kindsPanic(arrayOrSlice).(arrayOrSliceValue).Elem(i) | 247 » return v.panicIfNots(arrayOrSlice).(arrayOrSliceValue).Elem(i) |
248 } | 248 } |
249 | 249 |
250 var intKinds = []Kind{Int, Int8, Int16, Int32, Int64} | 250 var intKinds = []Kind{Int, Int8, Int16, Int32, Int64} |
251 | 251 |
252 // Int returns v's underlying value, as an int64. | 252 // Int returns v's underlying value, as an int64. |
253 // It panics if v's Kind is not a sized or unsized Int kind. | 253 // It panics if v's Kind is not a sized or unsized Int kind. |
254 func (v Value) Int() int64 { | 254 func (v Value) Int() int64 { |
255 » return v.kindsPanic(intKinds).(*intValue).Get() | 255 » return v.panicIfNots(intKinds).(*intValue).Get() |
256 } | 256 } |
257 | 257 |
258 // Interface returns v's value as an interface{}. | 258 // Interface returns v's value as an interface{}. |
259 // If v is a method obtained by invoking Value.Method | 259 // If v is a method obtained by invoking Value.Method |
260 // (as opposed to Type.Method), Interface cannot return an | 260 // (as opposed to Type.Method), Interface cannot return an |
261 // interface value, so it panics. | 261 // interface value, so it panics. |
262 func (v Value) Interface() interface{} { | 262 func (v Value) Interface() interface{} { |
263 return v.internal().Interface() | 263 return v.internal().Interface() |
264 } | 264 } |
265 | 265 |
266 // InterfaceData returns the interface v's value as a uintptr pair. | 266 // InterfaceData returns the interface v's value as a uintptr pair. |
267 // It panics if v's Kind is not Interface. | 267 // It panics if v's Kind is not Interface. |
268 func (v Value) InterfaceData() [2]uintptr { | 268 func (v Value) InterfaceData() [2]uintptr { |
269 » return v.kindPanic(Interface).(*InterfaceValue).Get() | 269 » return v.panicIfNot(Interface).(*interfaceValue).Get() |
270 } | 270 } |
271 | 271 |
272 var nilKinds = []Kind{Chan, Func, Interface, Map, Ptr, Slice} | 272 var nilKinds = []Kind{Chan, Func, Interface, Map, Ptr, Slice} |
273 | 273 |
274 type isNiller interface { | 274 type isNiller interface { |
275 IsNil() bool | 275 IsNil() bool |
276 } | 276 } |
277 | 277 |
278 // IsNil returns true if v is a nil value. | 278 // IsNil returns true if v is a nil value. |
279 // It panics if v's Kind is not Chan, Func, Interface, Map, Ptr, or Slice. | 279 // It panics if v's Kind is not Chan, Func, Interface, Map, Ptr, or Slice. |
niemeyer
2011/04/04 13:52:35
If CanBeNil is introduced, this may be documented
| |
280 func (v Value) IsNil() bool { | 280 func (v Value) IsNil() bool { |
281 » return v.kindsPanic(nilKinds).(isNiller).IsNil() | 281 » return v.panicIfNots(nilKinds).(isNiller).IsNil() |
282 } | 282 } |
283 | 283 |
284 // IsValid returns true if v represents a value. | 284 // IsValid returns true if v represents a value. |
285 // It returns false if v is the zero Value. | 285 // It returns false if v is the zero Value. |
286 // If IsValid returns false, all other methods except String panic. | 286 // If IsValid returns false, all other methods except String panic. |
287 // Most functions and methods never return an invalid value. | 287 // Most functions and methods never return an invalid value. |
288 // If one does, its documentation states the conditions explicitly. | 288 // If one does, its documentation states the conditions explicitly. |
289 func (v Value) IsValid() bool { | 289 func (v Value) IsValid() bool { |
290 return v.Internal != nil | 290 return v.Internal != nil |
291 } | 291 } |
292 | 292 |
293 // Kind returns v's Kind. | 293 // Kind returns v's Kind. |
294 // If v is the zero Value (IsValid returns false), Kind returns Invalid. | 294 // If v is the zero Value (IsValid returns false), Kind returns Invalid. |
295 func (v Value) Kind() Kind { | 295 func (v Value) Kind() Kind { |
296 if v.Internal == nil { | 296 if v.Internal == nil { |
297 return Invalid | 297 return Invalid |
298 } | 298 } |
299 return v.internal().Kind() | 299 return v.internal().Kind() |
300 } | 300 } |
301 | 301 |
302 var lenKinds = []Kind{Array, Chan, Map, Slice} | 302 var lenKinds = []Kind{Array, Chan, Map, Slice} |
303 | 303 |
304 type lenner interface { | 304 type lenner interface { |
305 Len() int | 305 Len() int |
306 } | 306 } |
307 | 307 |
308 // Len returns v's length. | 308 // Len returns v's length. |
309 // It panics if v's Kind is not Array, Chan, Map, or Slice. | 309 // It panics if v's Kind is not Array, Chan, Map, or Slice. |
310 func (v Value) Len() int { | 310 func (v Value) Len() int { |
311 » return v.kindsPanic(lenKinds).(lenner).Len() | 311 » return v.panicIfNots(lenKinds).(lenner).Len() |
312 } | 312 } |
313 | 313 |
314 // MapIndex returns the value associated with key in the map v. | 314 // MapIndex returns the value associated with key in the map v. |
315 // It panics if v's Kind is not Map. | 315 // It panics if v's Kind is not Map. |
316 // It returns the zero Value if key is not found in the map. | 316 // It returns the zero Value if key is not found in the map. |
317 func (v Value) MapIndex(key Value) Value { | 317 func (v Value) MapIndex(key Value) Value { |
318 » return v.kindPanic(Map).(*mapValue).Elem(key) | 318 » return v.panicIfNot(Map).(*mapValue).Elem(key) |
319 } | 319 } |
320 | 320 |
321 // MapKeys returns a slice containing all the keys present in the map, | 321 // MapKeys returns a slice containing all the keys present in the map, |
322 // in unspecified order. | 322 // in unspecified order. |
323 // It panics if v's Kind is not Map. | 323 // It panics if v's Kind is not Map. |
324 func (v Value) MapKeys() []Value { | 324 func (v Value) MapKeys() []Value { |
325 » return v.kindPanic(Map).(*mapValue).Keys() | 325 » return v.panicIfNot(Map).(*mapValue).Keys() |
326 } | 326 } |
327 | 327 |
328 // Method returns a function value corresponding to v's i'th method. | 328 // Method returns a function value corresponding to v's i'th method. |
329 // The arguments to a Call on the returned function should not include | 329 // The arguments to a Call on the returned function should not include |
330 // a receiver; the returned function will always use v as the receiver. | 330 // a receiver; the returned function will always use v as the receiver. |
331 func (v Value) Method(i int) Value { | 331 func (v Value) Method(i int) Value { |
332 return v.internal().Method(i) | 332 return v.internal().Method(i) |
333 } | 333 } |
334 | 334 |
335 // NumField returns the number of fields in the struct v. | 335 // NumField returns the number of fields in the struct v. |
336 // It panics if v's Kind is not Struct. | 336 // It panics if v's Kind is not Struct. |
337 func (v Value) NumField() int { | 337 func (v Value) NumField() int { |
338 » return v.kindPanic(Struct).(*structValue).NumField() | 338 » return v.panicIfNot(Struct).(*structValue).NumField() |
339 } | 339 } |
340 | 340 |
341 // OverflowComplex returns true if the complex128 x cannot be represented by v's type. | 341 // OverflowComplex returns true if the complex128 x cannot be represented by v's type. |
r
2011/04/02 18:45:33
not clear what this means, exactly. i mean, we hav
niemeyer
2011/04/04 13:52:35
s/type/Kind/ (v's type is Value).
Same for other
rsc
2011/04/05 16:29:45
You're being pedantic. v refers to the underlying
| |
342 // It panics if v's Kind is not Complex64 or Complex128. | 342 // It panics if v's Kind is not Complex64 or Complex128. |
343 func (v Value) OverflowComplex(x complex128) bool { | 343 func (v Value) OverflowComplex(x complex128) bool { |
344 » return v.kindsPanic(complexKinds).(*complexValue).Overflow(x) | 344 » return v.panicIfNots(complexKinds).(*complexValue).Overflow(x) |
345 } | 345 } |
346 | 346 |
347 // OverflowFloat returns true if the float64 x cannot be represented by v's type . | 347 // OverflowFloat returns true if the float64 x cannot be represented by v's type . |
348 // It panics if v's Kind is not Float32 or Float64. | 348 // It panics if v's Kind is not Float32 or Float64. |
349 func (v Value) OverflowFloat(x float64) bool { | 349 func (v Value) OverflowFloat(x float64) bool { |
350 » return v.kindsPanic(floatKinds).(*floatValue).Overflow(x) | 350 » return v.panicIfNots(floatKinds).(*floatValue).Overflow(x) |
351 } | 351 } |
352 | 352 |
353 // OverflowInt returns true if the int64 x cannot be represented by v's type. | 353 // OverflowInt returns true if the int64 x cannot be represented by v's type. |
354 // It panics if v's Kind is not a sized or unsized Int kind. | 354 // It panics if v's Kind is not a sized or unsized Int kind. |
355 func (v Value) OverflowInt(x int64) bool { | 355 func (v Value) OverflowInt(x int64) bool { |
356 » return v.kindsPanic(intKinds).(*intValue).Overflow(x) | 356 » return v.panicIfNots(intKinds).(*intValue).Overflow(x) |
357 } | 357 } |
358 | 358 |
359 // OverflowUint returns true if the uint64 x cannot be represented by v's type. | 359 // OverflowUint returns true if the uint64 x cannot be represented by v's type. |
360 // It panics if v's Kind is not a sized or unsized Uint kind. | 360 // It panics if v's Kind is not a sized or unsized Uint kind. |
361 func (v Value) OverflowUint(x uint64) bool { | 361 func (v Value) OverflowUint(x uint64) bool { |
362 » return v.kindsPanic(uintKinds).(*uintValue).Overflow(x) | 362 » return v.panicIfNots(uintKinds).(*uintValue).Overflow(x) |
363 } | 363 } |
364 | 364 |
365 var pointerKinds = []Kind{Chan, Func, Map, Ptr, Slice, UnsafePointer} | 365 var pointerKinds = []Kind{Chan, Func, Map, Ptr, Slice, UnsafePointer} |
366 | 366 |
367 type uintptrGetter interface { | 367 type uintptrGetter interface { |
368 Get() uintptr | 368 Get() uintptr |
369 } | 369 } |
370 | 370 |
371 // UnsafePointer returns v's value as a uintptr. | 371 // Pointer returns v's value as a uintptr. |
r
2011/04/02 18:45:33
it's called Pointer
| |
372 // It returns uintptr instead of unsafe.Pointer so that | 372 // It returns uintptr instead of unsafe.Pointer so that |
373 // code using reflect cannot obtain unsafe.Pointers | 373 // code using reflect cannot obtain unsafe.Pointers |
374 // without importing the unsafe package explicitly. | 374 // without importing the unsafe package explicitly. |
375 // It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer. | 375 // It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer. |
376 func (v Value) Pointer() uintptr { | 376 func (v Value) Pointer() uintptr { |
377 » return v.kindsPanic(pointerKinds).(uintptrGetter).Get() | 377 » return v.panicIfNots(pointerKinds).(uintptrGetter).Get() |
378 } | 378 } |
379 | 379 |
380 | 380 |
381 // Recv receives and returns a value from the channel v. | 381 // Recv receives and returns a value from the channel v. |
382 // It panics if v's Kind is not Chan. | 382 // It panics if v's Kind is not Chan. |
383 // The receive blocks until a value is ready. | 383 // The receive blocks until a value is ready. |
384 // The boolean value ok is true if the value x corresponds to a send | 384 // The boolean value ok is true if the value x corresponds to a send |
385 // on the channel, false if it is a zero value received because the channel is c losed. | 385 // on the channel, false if it is a zero value received because the channel is c losed. |
386 func (v Value) Recv() (x Value, ok bool) { | 386 func (v Value) Recv() (x Value, ok bool) { |
387 » return v.kindPanic(Chan).(*chanValue).Recv() | 387 » return v.panicIfNot(Chan).(*chanValue).Recv() |
388 } | 388 } |
389 | 389 |
390 // Send sends x on the channel v. | 390 // Send sends x on the channel v. |
391 // It panics if v's kind is not Chan or if x's type is not the same type as v's element type. | 391 // It panics if v's kind is not Chan or if x's type is not the same type as v's element type. |
392 func (v Value) Send(x Value) { | 392 func (v Value) Send(x Value) { |
393 » v.kindPanic(Chan).(*chanValue).Send(x) | 393 » v.panicIfNot(Chan).(*chanValue).Send(x) |
394 } | 394 } |
395 | 395 |
396 // Set assigns x to the value v; x must have the same type as v. | 396 // Set assigns x to the value v; x must have the same type as v. |
niemeyer
2011/04/04 13:52:35
s/same type/same Kind/
rsc
2011/04/05 16:29:45
No. It must have the same type. You can't assign
| |
397 // It panics if CanSet() returns false. | 397 // It panics if CanSet() returns false or if x is the zero Value. |
398 func (v Value) Set(x Value) { | 398 func (v Value) Set(x Value) { |
399 x.internal() | |
399 v.internal().SetValue(x) | 400 v.internal().SetValue(x) |
400 } | 401 } |
401 | 402 |
402 // SetBool sets v's underlying value. | 403 // SetBool sets v's underlying value. |
403 // It panics if v's Kind is not Bool or if CanSet() is false. | 404 // It panics if v's Kind is not Bool or if CanSet() is false. |
404 func (v Value) SetBool(x bool) { | 405 func (v Value) SetBool(x bool) { |
405 » v.kindPanic(Bool).(*boolValue).Set(x) | 406 » v.panicIfNot(Bool).(*boolValue).Set(x) |
406 } | 407 } |
407 | 408 |
408 // SetComplex sets v's underlying value to x. | 409 // SetComplex sets v's underlying value to x. |
409 // It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false . | 410 // It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false . |
410 func (v Value) SetComplex(x complex128) { | 411 func (v Value) SetComplex(x complex128) { |
411 » v.kindsPanic(complexKinds).(*complexValue).Set(x) | 412 » v.panicIfNots(complexKinds).(*complexValue).Set(x) |
412 } | 413 } |
413 | 414 |
414 // SetFloat sets v's underlying value to x. | 415 // SetFloat sets v's underlying value to x. |
415 // It panics if v's Kind is not Float32 or Float64, or if CanSet() is false. | 416 // It panics if v's Kind is not Float32 or Float64, or if CanSet() is false. |
416 func (v Value) SetFloat(x float64) { | 417 func (v Value) SetFloat(x float64) { |
417 » v.kindsPanic(floatKinds).(*floatValue).Set(x) | 418 » v.panicIfNots(floatKinds).(*floatValue).Set(x) |
418 } | 419 } |
419 | 420 |
420 // SetInt sets v's underlying value to x. | 421 // SetInt sets v's underlying value to x. |
421 // It panics if v's Kind is not a sized or unsized Int kind, or if CanSet() is f alse. | 422 // It panics if v's Kind is not a sized or unsized Int kind, or if CanSet() is f alse. |
422 func (v Value) SetInt(x int64) { | 423 func (v Value) SetInt(x int64) { |
423 » v.kindsPanic(intKinds).(*intValue).Set(x) | 424 » v.panicIfNots(intKinds).(*intValue).Set(x) |
424 } | 425 } |
425 | 426 |
426 // SetLen sets v's length to n. | 427 // SetLen sets v's length to n. |
427 // It panics if v's Kind is not Slice. | 428 // It panics if v's Kind is not Slice. |
428 func (v Value) SetLen(n int) { | 429 func (v Value) SetLen(n int) { |
429 » v.kindPanic(Slice).(*sliceValue).SetLen(n) | 430 » v.panicIfNot(Slice).(*sliceValue).SetLen(n) |
430 } | 431 } |
431 | 432 |
432 // SetMapElem sets the value associated with key in the map v to val. | 433 // SetMapIndex sets the value associated with key in the map v to val. |
r
2011/04/02 18:45:33
it's called SetMapIndex
| |
433 // It panics if v's Kind is not Map. | 434 // It panics if v's Kind is not Map. |
434 // If val is the zero Value, SetMapElem deletes the key from the map. | 435 // If val is the zero Value, SetMapIndex deletes the key from the map. |
niemeyer
2011/04/04 13:52:35
Some of the semantic confusion described can be se
rsc
2011/04/05 16:29:45
I really don't think this is confusing. The text
| |
435 func (v Value) SetMapIndex(key, val Value) { | 436 func (v Value) SetMapIndex(key, val Value) { |
436 » v.kindPanic(Map).(*mapValue).SetElem(key, val) | 437 » v.panicIfNot(Map).(*mapValue).SetElem(key, val) |
437 } | 438 } |
438 | 439 |
439 // SetUint sets v's underlying value to x. | 440 // SetUint sets v's underlying value to x. |
440 // It panics if v's Kind is not a sized or unsized Uint kind, or if CanSet() is false. | 441 // It panics if v's Kind is not a sized or unsized Uint kind, or if CanSet() is false. |
441 func (v Value) SetUint(x uint64) { | 442 func (v Value) SetUint(x uint64) { |
442 » v.kindsPanic(uintKinds).(*uintValue).Set(x) | 443 » v.panicIfNots(uintKinds).(*uintValue).Set(x) |
443 } | 444 } |
444 | 445 |
445 // SetPointer sets the unsafe.Pointer value v to x. | 446 // SetPointer sets the unsafe.Pointer value v to x. |
446 // It panics if v's Kind is not UnsafePointer. | 447 // It panics if v's Kind is not UnsafePointer. |
447 func (v Value) SetPointer(x unsafe.Pointer) { | 448 func (v Value) SetPointer(x unsafe.Pointer) { |
448 » v.kindPanic(UnsafePointer).(*unsafePointerValue).Set(x) | 449 » v.panicIfNot(UnsafePointer).(*unsafePointerValue).Set(x) |
449 } | 450 } |
450 | 451 |
451 // SetString sets v's underlying value to x. | 452 // SetString sets v's underlying value to x. |
452 // It panics if v's Kind is not String or if CanSet() is false. | 453 // It panics if v's Kind is not String or if CanSet() is false. |
453 func (v Value) SetString(x string) { | 454 func (v Value) SetString(x string) { |
454 » v.kindPanic(String).(*stringValue).Set(x) | 455 » v.panicIfNot(String).(*stringValue).Set(x) |
455 } | 456 } |
456 | 457 |
457 // BUG(rsc): Value.Slice should allow slicing arrays. | 458 // BUG(rsc): Value.Slice should allow slicing arrays. |
r
2011/04/02 18:45:33
can you just fix it?
| |
458 | 459 |
459 // Slice returns a slice of v. | 460 // Slice returns a slice of v. |
460 // It panics if v's Kind is not Slice. | 461 // It panics if v's Kind is not Slice. |
461 func (v Value) Slice(beg, end int) Value { | 462 func (v Value) Slice(beg, end int) Value { |
462 » return v.kindPanic(Slice).(*sliceValue).Slice(beg, end) | 463 » return v.panicIfNot(Slice).(*sliceValue).Slice(beg, end) |
463 } | 464 } |
464 | 465 |
465 // String returns the string v's underlying value, as a string. | 466 // String returns the string v's underlying value, as a string. |
466 // String is a special case because of Go's String method convention. | 467 // String is a special case because of Go's String method convention. |
467 // Unlike the other getters, it does not panic if v's Kind is not String. | 468 // Unlike the other getters, it does not panic if v's Kind is not String. |
468 // Instead, it returns a string of the form "<T value>" where T is v's type. | 469 // Instead, it returns a string of the form "<T value>" where T is v's type. |
469 func (v Value) String() string { | 470 func (v Value) String() string { |
470 vi := v.Internal | 471 vi := v.Internal |
471 if vi == nil { | 472 if vi == nil { |
472 return "<invalid Value>" | 473 return "<invalid Value>" |
473 } | 474 } |
474 if vi.Kind() == String { | 475 if vi.Kind() == String { |
475 return vi.(*stringValue).Get() | 476 return vi.(*stringValue).Get() |
476 } | 477 } |
477 return "<" + vi.Type().String() + " Value>" | 478 return "<" + vi.Type().String() + " Value>" |
478 } | 479 } |
479 | 480 |
480 // TryRecv attempts to receive a value from the channel v but will not block. | 481 // TryRecv attempts to receive a value from the channel v but will not block. |
481 // It panics if v's Kind is not Chan. | 482 // It panics if v's Kind is not Chan. |
482 // If the receive cannot finish without blocking, x is the zero Value. | 483 // If the receive cannot finish without blocking, x is the zero Value. |
483 // The boolean ok is true if the value x corresponds to a send | 484 // The boolean ok is true if the value x corresponds to a send |
484 // on the channel, false if it is a zero value received because the channel is c losed. | 485 // on the channel, false if it is a zero value received because the channel is c losed. |
485 func (v Value) TryRecv() (x Value, ok bool) { | 486 func (v Value) TryRecv() (x Value, ok bool) { |
486 » return v.kindPanic(Chan).(*chanValue).TryRecv() | 487 » return v.panicIfNot(Chan).(*chanValue).TryRecv() |
487 } | 488 } |
488 | 489 |
489 // TrySend attempts to send x on the channel v but will not block. | 490 // TrySend attempts to send x on the channel v but will not block. |
490 // It panics if v's Kind is not Chan. | 491 // It panics if v's Kind is not Chan. |
491 // It returns true if the value was sent, false otherwise. | 492 // It returns true if the value was sent, false otherwise. |
492 func (v Value) TrySend(x Value) bool { | 493 func (v Value) TrySend(x Value) bool { |
493 » return v.kindPanic(Chan).(*chanValue).TrySend(x) | 494 » return v.panicIfNot(Chan).(*chanValue).TrySend(x) |
494 } | 495 } |
495 | 496 |
496 // Type returns v's type. | 497 // Type returns v's type. |
niemeyer
2011/04/04 13:52:35
s/v's type/v's Type value/ ?
rsc
2011/04/05 16:29:45
No. Same as above.
| |
497 func (v Value) Type() Type { | 498 func (v Value) Type() Type { |
498 return v.internal().Type() | 499 return v.internal().Type() |
499 } | 500 } |
500 | 501 |
501 var uintKinds = []Kind{Uint, Uint8, Uint16, Uint32, Uint64, Uintptr} | 502 var uintKinds = []Kind{Uint, Uint8, Uint16, Uint32, Uint64, Uintptr} |
502 | 503 |
503 // Uint returns v's underlying value, as a uint64. | 504 // Uint returns v's underlying value, as a uint64. |
504 // It panics if v's Kind is not a sized or unsized Uint kind. | 505 // It panics if v's Kind is not a sized or unsized Uint kind. |
505 func (v Value) Uint() uint64 { | 506 func (v Value) Uint() uint64 { |
506 » return v.kindsPanic(uintKinds).(*uintValue).Get() | 507 » return v.panicIfNots(uintKinds).(*uintValue).Get() |
507 } | 508 } |
508 | 509 |
509 // UnsafeAddr returns a pointer to v's data. | 510 // UnsafeAddr returns a pointer to v's data. |
510 // It is for advanced clients that also import the "unsafe" package. | 511 // It is for advanced clients that also import the "unsafe" package. |
511 func (v Value) UnsafeAddr() uintptr { | 512 func (v Value) UnsafeAddr() uintptr { |
512 return v.internal().UnsafeAddr() | 513 return v.internal().UnsafeAddr() |
513 } | 514 } |
514 | 515 |
515 // valueInterface is the common interface to reflection values. | 516 // valueInterface is the common interface to reflection values. |
516 // The implementations of Value (e.g., arrayValue, structValue) | 517 // The implementations of Value (e.g., arrayValue, structValue) |
(...skipping 11 matching lines...) Expand all Loading... | |
528 // If CanSet returns false, calling the type-specific Set will panic. | 529 // If CanSet returns false, calling the type-specific Set will panic. |
529 CanSet() bool | 530 CanSet() bool |
530 | 531 |
531 // SetValue assigns v to the value; v must have the same type as the val ue. | 532 // SetValue assigns v to the value; v must have the same type as the val ue. |
532 SetValue(v Value) | 533 SetValue(v Value) |
533 | 534 |
534 // CanAddr returns true if the value's address can be obtained with Addr . | 535 // CanAddr returns true if the value's address can be obtained with Addr . |
535 // Such values are called addressable. A value is addressable if it is | 536 // Such values are called addressable. A value is addressable if it is |
536 // an element of a slice, an element of an addressable array, | 537 // an element of a slice, an element of an addressable array, |
537 // a field of an addressable struct, the result of dereferencing a point er, | 538 // a field of an addressable struct, the result of dereferencing a point er, |
538 » // or the result of a call to NewValue, MakeChan, MakeMap, or MakeZero. | 539 » // or the result of a call to NewValue, MakeChan, MakeMap, or Zero. |
539 // If CanAddr returns false, calling Addr will panic. | 540 // If CanAddr returns false, calling Addr will panic. |
540 CanAddr() bool | 541 CanAddr() bool |
541 | 542 |
542 // Addr returns the address of the value. | 543 // Addr returns the address of the value. |
543 // If the value is not addressable, Addr panics. | 544 // If the value is not addressable, Addr panics. |
544 // Addr is typically used to obtain a pointer to a struct field or slice element | 545 // Addr is typically used to obtain a pointer to a struct field or slice element |
545 // in order to call a method that requires a pointer receiver. | 546 // in order to call a method that requires a pointer receiver. |
546 Addr() Value | 547 Addr() Value |
547 | 548 |
548 // UnsafeAddr returns a pointer to the underlying data. | 549 // UnsafeAddr returns a pointer to the underlying data. |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
815 func (v *stringValue) Set(x string) { | 816 func (v *stringValue) Set(x string) { |
816 if !v.CanSet() { | 817 if !v.CanSet() { |
817 panic(cannotSet) | 818 panic(cannotSet) |
818 } | 819 } |
819 *(*string)(v.addr) = x | 820 *(*string)(v.addr) = x |
820 } | 821 } |
821 | 822 |
822 // Set sets v to the value x. | 823 // Set sets v to the value x. |
823 func (v *stringValue) SetValue(x Value) { | 824 func (v *stringValue) SetValue(x Value) { |
824 // Do the kind check explicitly, because x.String() does not. | 825 // Do the kind check explicitly, because x.String() does not. |
825 » v.Set(x.kindPanic(String).(*stringValue).Get()) | 826 » v.Set(x.panicIfNot(String).(*stringValue).Get()) |
826 } | 827 } |
827 | 828 |
828 // uintValue represents a uint value. | 829 // uintValue represents a uint value. |
829 type uintValue struct { | 830 type uintValue struct { |
830 value "uint" | 831 value "uint" |
831 } | 832 } |
832 | 833 |
833 // Get returns the underlying uuint value. | 834 // Get returns the underlying uuint value. |
834 func (v *uintValue) Get() uint64 { | 835 func (v *uintValue) Get() uint64 { |
835 switch v.typ.Kind() { | 836 switch v.typ.Kind() { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
898 if !v.CanSet() { | 899 if !v.CanSet() { |
899 panic(cannotSet) | 900 panic(cannotSet) |
900 } | 901 } |
901 *(*unsafe.Pointer)(v.addr) = x | 902 *(*unsafe.Pointer)(v.addr) = x |
902 } | 903 } |
903 | 904 |
904 // Set sets v to the value x. | 905 // Set sets v to the value x. |
905 func (v *unsafePointerValue) SetValue(x Value) { | 906 func (v *unsafePointerValue) SetValue(x Value) { |
906 // Do the kind check explicitly, because x.UnsafePointer | 907 // Do the kind check explicitly, because x.UnsafePointer |
907 // applies to more than just the UnsafePointer Kind. | 908 // applies to more than just the UnsafePointer Kind. |
908 » v.Set(unsafe.Pointer(x.kindPanic(UnsafePointer).(*unsafePointerValue).Ge t())) | 909 » v.Set(unsafe.Pointer(x.panicIfNot(UnsafePointer).(*unsafePointerValue).G et())) |
909 } | 910 } |
910 | 911 |
911 func typesMustMatch(t1, t2 Type) { | 912 func typesMustMatch(t1, t2 Type) { |
912 if t1 != t2 { | 913 if t1 != t2 { |
913 panic("type mismatch: " + t1.String() + " != " + t2.String()) | 914 panic("type mismatch: " + t1.String() + " != " + t2.String()) |
914 } | 915 } |
915 } | 916 } |
916 | 917 |
917 /* | 918 /* |
918 * array | 919 * array |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
953 } | 954 } |
954 t := MakeSlice(s.Type(), i1, m) | 955 t := MakeSlice(s.Type(), i1, m) |
955 Copy(t, s) | 956 Copy(t, s) |
956 return t, i0, i1 | 957 return t, i0, i1 |
957 } | 958 } |
958 | 959 |
959 // Append appends the values x to a slice s and returns the resulting slice. | 960 // Append appends the values x to a slice s and returns the resulting slice. |
960 // Each x must have the same type as s' element type. | 961 // Each x must have the same type as s' element type. |
961 func Append(s Value, x ...Value) Value { | 962 func Append(s Value, x ...Value) Value { |
962 s, i0, i1 := grow(s, len(x)) | 963 s, i0, i1 := grow(s, len(x)) |
963 » sa := s.kindPanic(Slice).(*sliceValue) | 964 » sa := s.panicIfNot(Slice).(*sliceValue) |
964 for i, j := i0, 0; i < i1; i, j = i+1, j+1 { | 965 for i, j := i0, 0; i < i1; i, j = i+1, j+1 { |
965 sa.Elem(i).Set(x[j]) | 966 sa.Elem(i).Set(x[j]) |
966 } | 967 } |
967 return s | 968 return s |
968 } | 969 } |
969 | 970 |
970 // AppendSlice appends a slice t to a slice s and returns the resulting slice. | 971 // AppendSlice appends a slice t to a slice s and returns the resulting slice. |
971 // The slices s and t must have the same element type. | 972 // The slices s and t must have the same element type. |
972 func AppendSlice(s, t Value) Value { | 973 func AppendSlice(s, t Value) Value { |
973 s, i0, i1 := grow(s, t.Len()) | 974 s, i0, i1 := grow(s, t.Len()) |
974 Copy(s.Slice(i0, i1), t) | 975 Copy(s.Slice(i0, i1), t) |
975 return s | 976 return s |
976 } | 977 } |
977 | 978 |
978 // Copy copies the contents of src into dst until either | 979 // Copy copies the contents of src into dst until either |
979 // dst has been filled or src has been exhausted. | 980 // dst has been filled or src has been exhausted. |
980 // It returns the number of elements copied. | 981 // It returns the number of elements copied. |
981 // Dst and src each must be a slice or array, and they | 982 // Dst and src each must be a slice or array, and they |
982 // must have the same element type. | 983 // must have the same element type. |
983 func Copy(dst, src Value) int { | 984 func Copy(dst, src Value) int { |
984 // TODO: This will have to move into the runtime | 985 // TODO: This will have to move into the runtime |
985 // once the real gc goes in. | 986 // once the real gc goes in. |
986 de := dst.Type().Elem() | 987 de := dst.Type().Elem() |
987 se := src.Type().Elem() | 988 se := src.Type().Elem() |
988 typesMustMatch(de, se) | 989 typesMustMatch(de, se) |
989 n := dst.Len() | 990 n := dst.Len() |
990 if xn := src.Len(); n > xn { | 991 if xn := src.Len(); n > xn { |
991 n = xn | 992 n = xn |
992 } | 993 } |
993 » memmove(dst.kindsPanic(arrayOrSlice).(arrayOrSliceValue).addr(), | 994 » memmove(dst.panicIfNots(arrayOrSlice).(arrayOrSliceValue).addr(), |
994 » » src.kindsPanic(arrayOrSlice).(arrayOrSliceValue).addr(), | 995 » » src.panicIfNots(arrayOrSlice).(arrayOrSliceValue).addr(), |
995 uintptr(n)*de.Size()) | 996 uintptr(n)*de.Size()) |
996 return n | 997 return n |
997 } | 998 } |
998 | 999 |
999 // An arrayValue represents an array. | 1000 // An arrayValue represents an array. |
1000 type arrayValue struct { | 1001 type arrayValue struct { |
1001 value "array" | 1002 value "array" |
1002 } | 1003 } |
1003 | 1004 |
1004 // Len returns the length of the array. | 1005 // Len returns the length of the array. |
(...skipping 10 matching lines...) Expand all Loading... | |
1015 func (v *arrayValue) Set(x *arrayValue) { | 1016 func (v *arrayValue) Set(x *arrayValue) { |
1016 if !v.CanSet() { | 1017 if !v.CanSet() { |
1017 panic(cannotSet) | 1018 panic(cannotSet) |
1018 } | 1019 } |
1019 typesMustMatch(v.typ, x.typ) | 1020 typesMustMatch(v.typ, x.typ) |
1020 Copy(Value{v}, Value{x}) | 1021 Copy(Value{v}, Value{x}) |
1021 } | 1022 } |
1022 | 1023 |
1023 // Set sets v to the value x. | 1024 // Set sets v to the value x. |
1024 func (v *arrayValue) SetValue(x Value) { | 1025 func (v *arrayValue) SetValue(x Value) { |
1025 » v.Set(x.kindPanic(Array).(*arrayValue)) | 1026 » v.Set(x.panicIfNot(Array).(*arrayValue)) |
1026 } | 1027 } |
1027 | 1028 |
1028 // Elem returns the i'th element of v. | 1029 // Elem returns the i'th element of v. |
1029 func (v *arrayValue) Elem(i int) Value { | 1030 func (v *arrayValue) Elem(i int) Value { |
1030 typ := v.typ.Elem() | 1031 typ := v.typ.Elem() |
1031 n := v.Len() | 1032 n := v.Len() |
1032 if i < 0 || i >= n { | 1033 if i < 0 || i >= n { |
1033 panic("array index out of bounds") | 1034 panic("array index out of bounds") |
1034 } | 1035 } |
1035 p := addr(uintptr(v.addr()) + uintptr(i)*typ.Size()) | 1036 p := addr(uintptr(v.addr()) + uintptr(i)*typ.Size()) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1081 func (v *sliceValue) Set(x *sliceValue) { | 1082 func (v *sliceValue) Set(x *sliceValue) { |
1082 if !v.CanSet() { | 1083 if !v.CanSet() { |
1083 panic(cannotSet) | 1084 panic(cannotSet) |
1084 } | 1085 } |
1085 typesMustMatch(v.typ, x.typ) | 1086 typesMustMatch(v.typ, x.typ) |
1086 *v.slice() = *x.slice() | 1087 *v.slice() = *x.slice() |
1087 } | 1088 } |
1088 | 1089 |
1089 // Set sets v to the value x. | 1090 // Set sets v to the value x. |
1090 func (v *sliceValue) SetValue(x Value) { | 1091 func (v *sliceValue) SetValue(x Value) { |
1091 » v.Set(x.kindPanic(Slice).(*sliceValue)) | 1092 » v.Set(x.panicIfNot(Slice).(*sliceValue)) |
1092 } | 1093 } |
1093 | 1094 |
1094 // Get returns the uintptr address of the v.Cap()'th element. This gives | 1095 // Get returns the uintptr address of the v.Cap()'th element. This gives |
1095 // the same result for all slices of the same array. | 1096 // the same result for all slices of the same array. |
1096 // It is mainly useful for printing. | 1097 // It is mainly useful for printing. |
1097 func (v *sliceValue) Get() uintptr { | 1098 func (v *sliceValue) Get() uintptr { |
1098 typ := v.typ | 1099 typ := v.typ |
1099 return uintptr(v.addr()) + uintptr(v.Cap())*typ.Elem().Size() | 1100 return uintptr(v.addr()) + uintptr(v.Cap())*typ.Elem().Size() |
1100 } | 1101 } |
1101 | 1102 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1166 func (v *chanValue) Set(x *chanValue) { | 1167 func (v *chanValue) Set(x *chanValue) { |
1167 if !v.CanSet() { | 1168 if !v.CanSet() { |
1168 panic(cannotSet) | 1169 panic(cannotSet) |
1169 } | 1170 } |
1170 typesMustMatch(v.typ, x.typ) | 1171 typesMustMatch(v.typ, x.typ) |
1171 *(*uintptr)(v.addr) = *(*uintptr)(x.addr) | 1172 *(*uintptr)(v.addr) = *(*uintptr)(x.addr) |
1172 } | 1173 } |
1173 | 1174 |
1174 // Set sets v to the value x. | 1175 // Set sets v to the value x. |
1175 func (v *chanValue) SetValue(x Value) { | 1176 func (v *chanValue) SetValue(x Value) { |
1176 » v.Set(x.kindPanic(Chan).(*chanValue)) | 1177 » v.Set(x.panicIfNot(Chan).(*chanValue)) |
1177 } | 1178 } |
1178 | 1179 |
1179 // Get returns the uintptr value of v. | 1180 // Get returns the uintptr value of v. |
1180 // It is mainly useful for printing. | 1181 // It is mainly useful for printing. |
1181 func (v *chanValue) Get() uintptr { return *(*uintptr)(v.addr) } | 1182 func (v *chanValue) Get() uintptr { return *(*uintptr)(v.addr) } |
1182 | 1183 |
1183 // implemented in ../pkg/runtime/reflect.cgo | 1184 // implemented in ../pkg/runtime/reflect.cgo |
1184 func makechan(typ *runtime.ChanType, size uint32) (ch *byte) | 1185 func makechan(typ *runtime.ChanType, size uint32) (ch *byte) |
1185 func chansend(ch, val *byte, selected *bool) | 1186 func chansend(ch, val *byte, selected *bool) |
1186 func chanrecv(ch, val *byte, selected *bool, ok *bool) | 1187 func chanrecv(ch, val *byte, selected *bool, ok *bool) |
(...skipping 28 matching lines...) Expand all Loading... | |
1215 chansend(ch, (*byte)(x.internal().getAddr()), selected) | 1216 chansend(ch, (*byte)(x.internal().getAddr()), selected) |
1216 } | 1217 } |
1217 | 1218 |
1218 // internal recv; non-blocking if selected != nil | 1219 // internal recv; non-blocking if selected != nil |
1219 func (v *chanValue) recv(selected *bool) (Value, bool) { | 1220 func (v *chanValue) recv(selected *bool) (Value, bool) { |
1220 t := v.Type() | 1221 t := v.Type() |
1221 if t.ChanDir()&RecvDir == 0 { | 1222 if t.ChanDir()&RecvDir == 0 { |
1222 panic("recv on send-only channel") | 1223 panic("recv on send-only channel") |
1223 } | 1224 } |
1224 ch := *(**byte)(v.addr) | 1225 ch := *(**byte)(v.addr) |
1225 » x := MakeZero(t.Elem()) | 1226 » x := Zero(t.Elem()) |
1226 var ok bool | 1227 var ok bool |
1227 chanrecv(ch, (*byte)(x.internal().getAddr()), selected, &ok) | 1228 chanrecv(ch, (*byte)(x.internal().getAddr()), selected, &ok) |
1228 return x, ok | 1229 return x, ok |
1229 } | 1230 } |
1230 | 1231 |
1231 // Send sends x on the channel v. | 1232 // Send sends x on the channel v. |
1232 func (v *chanValue) Send(x Value) { v.send(x, nil) } | 1233 func (v *chanValue) Send(x Value) { v.send(x, nil) } |
1233 | 1234 |
1234 // Recv receives and returns a value from the channel v. | 1235 // Recv receives and returns a value from the channel v. |
1235 // The receive blocks until a value is ready. | 1236 // The receive blocks until a value is ready. |
(...skipping 29 matching lines...) Expand all Loading... | |
1265 func MakeChan(typ Type, buffer int) Value { | 1266 func MakeChan(typ Type, buffer int) Value { |
1266 if typ.Kind() != Chan { | 1267 if typ.Kind() != Chan { |
1267 panic("reflect: MakeChan of non-chan type") | 1268 panic("reflect: MakeChan of non-chan type") |
1268 } | 1269 } |
1269 if buffer < 0 { | 1270 if buffer < 0 { |
1270 panic("MakeChan: negative buffer size") | 1271 panic("MakeChan: negative buffer size") |
1271 } | 1272 } |
1272 if typ.ChanDir() != BothDir { | 1273 if typ.ChanDir() != BothDir { |
1273 panic("MakeChan: unidirectional channel type") | 1274 panic("MakeChan: unidirectional channel type") |
1274 } | 1275 } |
1275 » v := MakeZero(typ) | 1276 » v := Zero(typ) |
1276 » ch := v.kindPanic(Chan).(*chanValue) | 1277 » ch := v.panicIfNot(Chan).(*chanValue) |
1277 *(**byte)(ch.addr) = makechan((*runtime.ChanType)(unsafe.Pointer(typ.(*c ommonType))), uint32(buffer)) | 1278 *(**byte)(ch.addr) = makechan((*runtime.ChanType)(unsafe.Pointer(typ.(*c ommonType))), uint32(buffer)) |
1278 return v | 1279 return v |
1279 } | 1280 } |
1280 | 1281 |
1281 /* | 1282 /* |
1282 * func | 1283 * func |
1283 */ | 1284 */ |
1284 | 1285 |
1285 // A funcValue represents a function value. | 1286 // A funcValue represents a function value. |
1286 type funcValue struct { | 1287 type funcValue struct { |
(...skipping 14 matching lines...) Expand all Loading... | |
1301 func (v *funcValue) Set(x *funcValue) { | 1302 func (v *funcValue) Set(x *funcValue) { |
1302 if !v.CanSet() { | 1303 if !v.CanSet() { |
1303 panic(cannotSet) | 1304 panic(cannotSet) |
1304 } | 1305 } |
1305 typesMustMatch(v.typ, x.typ) | 1306 typesMustMatch(v.typ, x.typ) |
1306 *(*uintptr)(v.addr) = *(*uintptr)(x.addr) | 1307 *(*uintptr)(v.addr) = *(*uintptr)(x.addr) |
1307 } | 1308 } |
1308 | 1309 |
1309 // Set sets v to the value x. | 1310 // Set sets v to the value x. |
1310 func (v *funcValue) SetValue(x Value) { | 1311 func (v *funcValue) SetValue(x Value) { |
1311 » v.Set(x.kindPanic(Func).(*funcValue)) | 1312 » v.Set(x.panicIfNot(Func).(*funcValue)) |
1312 } | 1313 } |
1313 | 1314 |
1314 // Method returns a funcValue corresponding to v's i'th method. | 1315 // Method returns a funcValue corresponding to v's i'th method. |
1315 // The arguments to a Call on the returned funcValue | 1316 // The arguments to a Call on the returned funcValue |
1316 // should not include a receiver; the funcValue will use v | 1317 // should not include a receiver; the funcValue will use v |
1317 // as the receiver. | 1318 // as the receiver. |
1318 func (v *value) Method(i int) Value { | 1319 func (v *value) Method(i int) Value { |
1319 t := v.Type().uncommon() | 1320 t := v.Type().uncommon() |
1320 if t == nil || i < 0 || i >= len(t.methods) { | 1321 if t == nil || i < 0 || i >= len(t.methods) { |
1321 panic("reflect: Method index out of range") | 1322 panic("reflect: Method index out of range") |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1432 call(*(**byte)(fv.addr), (*byte)(addr(ptr)), uint32(size)) | 1433 call(*(**byte)(fv.addr), (*byte)(addr(ptr)), uint32(size)) |
1433 | 1434 |
1434 // Copy return values out of args. | 1435 // Copy return values out of args. |
1435 // | 1436 // |
1436 // TODO(rsc): revisit like above. | 1437 // TODO(rsc): revisit like above. |
1437 ret := make([]Value, nout) | 1438 ret := make([]Value, nout) |
1438 for i := 0; i < nout; i++ { | 1439 for i := 0; i < nout; i++ { |
1439 tv := t.Out(i) | 1440 tv := t.Out(i) |
1440 a := uintptr(tv.Align()) | 1441 a := uintptr(tv.Align()) |
1441 off = (off + a - 1) &^ (a - 1) | 1442 off = (off + a - 1) &^ (a - 1) |
1442 » » v := MakeZero(tv) | 1443 » » v := Zero(tv) |
1443 n := tv.Size() | 1444 n := tv.Size() |
1444 memmove(v.internal().getAddr(), addr(ptr+off), n) | 1445 memmove(v.internal().getAddr(), addr(ptr+off), n) |
1445 ret[i] = v | 1446 ret[i] = v |
1446 off += n | 1447 off += n |
1447 } | 1448 } |
1448 | 1449 |
1449 return ret | 1450 return ret |
1450 } | 1451 } |
1451 | 1452 |
1452 /* | 1453 /* |
1453 * interface | 1454 * interface |
1454 */ | 1455 */ |
1455 | 1456 |
1456 // An InterfaceValue represents an interface value. | 1457 // An interfaceValue represents an interface value. |
1457 type InterfaceValue struct { | 1458 type interfaceValue struct { |
1458 value "interface" | 1459 value "interface" |
1459 } | 1460 } |
1460 | 1461 |
1461 // IsNil returns whether v is a nil interface value. | 1462 // IsNil returns whether v is a nil interface value. |
1462 func (v *InterfaceValue) IsNil() bool { return v.Interface() == nil } | 1463 func (v *interfaceValue) IsNil() bool { return v.Interface() == nil } |
1463 | 1464 |
1464 // No single uinptr Get because v.Interface() is available. | 1465 // No single uinptr Get because v.Interface() is available. |
1465 | 1466 |
1466 // Get returns the two words that represent an interface in the runtime. | 1467 // Get returns the two words that represent an interface in the runtime. |
1467 // Those words are useful only when playing unsafe games. | 1468 // Those words are useful only when playing unsafe games. |
1468 func (v *InterfaceValue) Get() [2]uintptr { | 1469 func (v *interfaceValue) Get() [2]uintptr { |
1469 return *(*[2]uintptr)(v.addr) | 1470 return *(*[2]uintptr)(v.addr) |
1470 } | 1471 } |
1471 | 1472 |
1472 // Elem returns the concrete value stored in the interface value v. | 1473 // Elem returns the concrete value stored in the interface value v. |
1473 func (v *InterfaceValue) Elem() Value { return NewValue(v.Interface()) } | 1474 func (v *interfaceValue) Elem() Value { return NewValue(v.Interface()) } |
1474 | 1475 |
1475 // ../runtime/reflect.cgo | 1476 // ../runtime/reflect.cgo |
1476 func setiface(typ *interfaceType, x *interface{}, addr addr) | 1477 func setiface(typ *interfaceType, x *interface{}, addr addr) |
1477 | 1478 |
1478 // Set assigns x to v. | 1479 // Set assigns x to v. |
1479 func (v *InterfaceValue) Set(x Value) { | 1480 func (v *interfaceValue) Set(x Value) { |
1480 » var i interface{} | 1481 » i := x.Interface() |
1481 » if x.IsValid() { | |
1482 » » i = x.Interface() | |
1483 » } | |
1484 if !v.CanSet() { | 1482 if !v.CanSet() { |
1485 panic(cannotSet) | 1483 panic(cannotSet) |
1486 } | 1484 } |
1487 // Two different representations; see comment in Get. | 1485 // Two different representations; see comment in Get. |
1488 // Empty interface is easy. | 1486 // Empty interface is easy. |
1489 t := (*interfaceType)(unsafe.Pointer(v.typ.(*commonType))) | 1487 t := (*interfaceType)(unsafe.Pointer(v.typ.(*commonType))) |
1490 if t.NumMethod() == 0 { | 1488 if t.NumMethod() == 0 { |
1491 *(*interface{})(v.addr) = i | 1489 *(*interface{})(v.addr) = i |
1492 return | 1490 return |
1493 } | 1491 } |
1494 | 1492 |
1495 // Non-empty interface requires a runtime check. | 1493 // Non-empty interface requires a runtime check. |
1496 setiface(t, &i, v.addr) | 1494 setiface(t, &i, v.addr) |
1497 } | 1495 } |
1498 | 1496 |
1499 // Set sets v to the value x. | 1497 // Set sets v to the value x. |
1500 func (v *InterfaceValue) SetValue(x Value) { v.Set(x) } | 1498 func (v *interfaceValue) SetValue(x Value) { v.Set(x) } |
1501 | 1499 |
1502 // Method returns a funcValue corresponding to v's i'th method. | 1500 // Method returns a funcValue corresponding to v's i'th method. |
1503 // The arguments to a Call on the returned funcValue | 1501 // The arguments to a Call on the returned funcValue |
1504 // should not include a receiver; the funcValue will use v | 1502 // should not include a receiver; the funcValue will use v |
1505 // as the receiver. | 1503 // as the receiver. |
1506 func (v *InterfaceValue) Method(i int) Value { | 1504 func (v *interfaceValue) Method(i int) Value { |
1507 t := (*interfaceType)(unsafe.Pointer(v.Type().(*commonType))) | 1505 t := (*interfaceType)(unsafe.Pointer(v.Type().(*commonType))) |
1508 if t == nil || i < 0 || i >= len(t.methods) { | 1506 if t == nil || i < 0 || i >= len(t.methods) { |
1509 panic("reflect: Method index out of range") | 1507 panic("reflect: Method index out of range") |
1510 } | 1508 } |
1511 p := &t.methods[i] | 1509 p := &t.methods[i] |
1512 | 1510 |
1513 // Interface is two words: itable, data. | 1511 // Interface is two words: itable, data. |
1514 tab := *(**runtime.Itable)(v.addr) | 1512 tab := *(**runtime.Itable)(v.addr) |
1515 data := &value{Typeof((*byte)(nil)), addr(uintptr(v.addr) + ptrSize), 0} | 1513 data := &value{Typeof((*byte)(nil)), addr(uintptr(v.addr) + ptrSize), 0} |
1516 | 1514 |
(...skipping 24 matching lines...) Expand all Loading... | |
1541 if x == nil { | 1539 if x == nil { |
1542 *(**uintptr)(v.addr) = nil | 1540 *(**uintptr)(v.addr) = nil |
1543 return | 1541 return |
1544 } | 1542 } |
1545 typesMustMatch(v.typ, x.typ) | 1543 typesMustMatch(v.typ, x.typ) |
1546 *(*uintptr)(v.addr) = *(*uintptr)(x.addr) | 1544 *(*uintptr)(v.addr) = *(*uintptr)(x.addr) |
1547 } | 1545 } |
1548 | 1546 |
1549 // Set sets v to the value x. | 1547 // Set sets v to the value x. |
1550 func (v *mapValue) SetValue(x Value) { | 1548 func (v *mapValue) SetValue(x Value) { |
1551 » if !x.IsValid() { | 1549 » v.Set(x.panicIfNot(Map).(*mapValue)) |
1552 » » v.Set(nil) | |
1553 » » return | |
1554 » } | |
1555 » v.Set(x.kindPanic(Map).(*mapValue)) | |
1556 } | 1550 } |
1557 | 1551 |
1558 // Get returns the uintptr value of v. | 1552 // Get returns the uintptr value of v. |
1559 // It is mainly useful for printing. | 1553 // It is mainly useful for printing. |
1560 func (v *mapValue) Get() uintptr { return *(*uintptr)(v.addr) } | 1554 func (v *mapValue) Get() uintptr { return *(*uintptr)(v.addr) } |
1561 | 1555 |
1562 // implemented in ../pkg/runtime/reflect.cgo | 1556 // implemented in ../pkg/runtime/reflect.cgo |
1563 func mapaccess(m, key, val *byte) bool | 1557 func mapaccess(m, key, val *byte) bool |
1564 func mapassign(m, key, val *byte) | 1558 func mapassign(m, key, val *byte) |
1565 func maplen(m *byte) int32 | 1559 func maplen(m *byte) int32 |
1566 func mapiterinit(m *byte) *byte | 1560 func mapiterinit(m *byte) *byte |
1567 func mapiternext(it *byte) | 1561 func mapiternext(it *byte) |
1568 func mapiterkey(it *byte, key *byte) bool | 1562 func mapiterkey(it *byte, key *byte) bool |
1569 func makemap(t *runtime.MapType) *byte | 1563 func makemap(t *runtime.MapType) *byte |
1570 | 1564 |
1571 // Elem returns the value associated with key in the map v. | 1565 // Elem returns the value associated with key in the map v. |
1572 // It returns nil if key is not found in the map. | 1566 // It returns nil if key is not found in the map. |
1573 func (v *mapValue) Elem(key Value) Value { | 1567 func (v *mapValue) Elem(key Value) Value { |
1574 t := v.Type() | 1568 t := v.Type() |
1575 typesMustMatch(t.Key(), key.Type()) | 1569 typesMustMatch(t.Key(), key.Type()) |
1576 m := *(**byte)(v.addr) | 1570 m := *(**byte)(v.addr) |
1577 if m == nil { | 1571 if m == nil { |
1578 return Value{} | 1572 return Value{} |
1579 } | 1573 } |
1580 » newval := MakeZero(t.Elem()) | 1574 » newval := Zero(t.Elem()) |
1581 if !mapaccess(m, (*byte)(key.internal().getAddr()), (*byte)(newval.inter nal().getAddr())) { | 1575 if !mapaccess(m, (*byte)(key.internal().getAddr()), (*byte)(newval.inter nal().getAddr())) { |
1582 return Value{} | 1576 return Value{} |
1583 } | 1577 } |
1584 return newval | 1578 return newval |
1585 } | 1579 } |
1586 | 1580 |
1587 // SetElem sets the value associated with key in the map v to val. | 1581 // SetElem sets the value associated with key in the map v to val. |
1588 // If val is nil, Put deletes the key from map. | 1582 // If val is nil, Put deletes the key from map. |
1589 func (v *mapValue) SetElem(key, val Value) { | 1583 func (v *mapValue) SetElem(key, val Value) { |
1590 t := v.Type() | 1584 t := v.Type() |
(...skipping 22 matching lines...) Expand all Loading... | |
1613 tk := v.Type().Key() | 1607 tk := v.Type().Key() |
1614 m := *(**byte)(v.addr) | 1608 m := *(**byte)(v.addr) |
1615 mlen := int32(0) | 1609 mlen := int32(0) |
1616 if m != nil { | 1610 if m != nil { |
1617 mlen = maplen(m) | 1611 mlen = maplen(m) |
1618 } | 1612 } |
1619 it := mapiterinit(m) | 1613 it := mapiterinit(m) |
1620 a := make([]Value, mlen) | 1614 a := make([]Value, mlen) |
1621 var i int | 1615 var i int |
1622 for i = 0; i < len(a); i++ { | 1616 for i = 0; i < len(a); i++ { |
1623 » » k := MakeZero(tk) | 1617 » » k := Zero(tk) |
1624 if !mapiterkey(it, (*byte)(k.internal().getAddr())) { | 1618 if !mapiterkey(it, (*byte)(k.internal().getAddr())) { |
1625 break | 1619 break |
1626 } | 1620 } |
1627 a[i] = k | 1621 a[i] = k |
1628 mapiternext(it) | 1622 mapiternext(it) |
1629 } | 1623 } |
1630 return a[0:i] | 1624 return a[0:i] |
1631 } | 1625 } |
1632 | 1626 |
1633 // MakeMap creates a new map of the specified type. | 1627 // MakeMap creates a new map of the specified type. |
1634 func MakeMap(typ Type) Value { | 1628 func MakeMap(typ Type) Value { |
1635 if typ.Kind() != Map { | 1629 if typ.Kind() != Map { |
1636 panic("reflect: MakeMap of non-map type") | 1630 panic("reflect: MakeMap of non-map type") |
1637 } | 1631 } |
1638 » v := MakeZero(typ) | 1632 » v := Zero(typ) |
1639 » m := v.kindPanic(Map).(*mapValue) | 1633 » m := v.panicIfNot(Map).(*mapValue) |
1640 *(**byte)(m.addr) = makemap((*runtime.MapType)(unsafe.Pointer(typ.(*comm onType)))) | 1634 *(**byte)(m.addr) = makemap((*runtime.MapType)(unsafe.Pointer(typ.(*comm onType)))) |
1641 return v | 1635 return v |
1642 } | 1636 } |
1643 | 1637 |
1644 /* | 1638 /* |
1645 * ptr | 1639 * ptr |
1646 */ | 1640 */ |
1647 | 1641 |
1648 // A ptrValue represents a pointer. | 1642 // A ptrValue represents a pointer. |
1649 type ptrValue struct { | 1643 type ptrValue struct { |
(...skipping 21 matching lines...) Expand all Loading... | |
1671 panic("cannot copy pointer obtained from unexported struct field ") | 1665 panic("cannot copy pointer obtained from unexported struct field ") |
1672 } | 1666 } |
1673 typesMustMatch(v.typ, x.typ) | 1667 typesMustMatch(v.typ, x.typ) |
1674 // TODO: This will have to move into the runtime | 1668 // TODO: This will have to move into the runtime |
1675 // once the new gc goes in | 1669 // once the new gc goes in |
1676 *(*uintptr)(v.addr) = *(*uintptr)(x.addr) | 1670 *(*uintptr)(v.addr) = *(*uintptr)(x.addr) |
1677 } | 1671 } |
1678 | 1672 |
1679 // Set sets v to the value x. | 1673 // Set sets v to the value x. |
1680 func (v *ptrValue) SetValue(x Value) { | 1674 func (v *ptrValue) SetValue(x Value) { |
1681 » if !x.IsValid() { | 1675 » v.Set(x.panicIfNot(Ptr).(*ptrValue)) |
1682 » » v.Set(nil) | |
1683 » » return | |
1684 » } | |
1685 » v.Set(x.kindPanic(Ptr).(*ptrValue)) | |
1686 } | 1676 } |
1687 | 1677 |
1688 // PointTo changes v to point to x. | 1678 // PointTo changes v to point to x. |
1689 // If x is a nil Value, PointTo sets v to nil. | 1679 // If x is a nil Value, PointTo sets v to nil. |
1690 func (v *ptrValue) PointTo(x Value) { | 1680 func (v *ptrValue) PointTo(x Value) { |
1691 if !x.IsValid() { | 1681 if !x.IsValid() { |
1692 *(**uintptr)(v.addr) = nil | 1682 *(**uintptr)(v.addr) = nil |
1693 return | 1683 return |
1694 } | 1684 } |
1695 if !x.CanSet() { | 1685 if !x.CanSet() { |
(...skipping 18 matching lines...) Expand all Loading... | |
1714 return newValue(v.typ.Elem(), *(*addr)(v.addr), flag) | 1704 return newValue(v.typ.Elem(), *(*addr)(v.addr), flag) |
1715 } | 1705 } |
1716 | 1706 |
1717 // Indirect returns the value that v points to. | 1707 // Indirect returns the value that v points to. |
1718 // If v is a nil pointer, Indirect returns a nil Value. | 1708 // If v is a nil pointer, Indirect returns a nil Value. |
1719 // If v is not a pointer, Indirect returns v. | 1709 // If v is not a pointer, Indirect returns v. |
1720 func Indirect(v Value) Value { | 1710 func Indirect(v Value) Value { |
1721 if v.Kind() != Ptr { | 1711 if v.Kind() != Ptr { |
1722 return v | 1712 return v |
1723 } | 1713 } |
1724 » return v.kindPanic(Ptr).(*ptrValue).Elem() | 1714 » return v.panicIfNot(Ptr).(*ptrValue).Elem() |
1725 } | 1715 } |
1726 | 1716 |
1727 /* | 1717 /* |
1728 * struct | 1718 * struct |
1729 */ | 1719 */ |
1730 | 1720 |
1731 // A structValue represents a struct value. | 1721 // A structValue represents a struct value. |
1732 type structValue struct { | 1722 type structValue struct { |
1733 value "struct" | 1723 value "struct" |
1734 } | 1724 } |
1735 | 1725 |
1736 // Set assigns x to v. | 1726 // Set assigns x to v. |
1737 // The new value x must have the same type as v. | 1727 // The new value x must have the same type as v. |
1738 func (v *structValue) Set(x *structValue) { | 1728 func (v *structValue) Set(x *structValue) { |
1739 // TODO: This will have to move into the runtime | 1729 // TODO: This will have to move into the runtime |
1740 // once the gc goes in. | 1730 // once the gc goes in. |
1741 if !v.CanSet() { | 1731 if !v.CanSet() { |
1742 panic(cannotSet) | 1732 panic(cannotSet) |
1743 } | 1733 } |
1744 typesMustMatch(v.typ, x.typ) | 1734 typesMustMatch(v.typ, x.typ) |
1745 memmove(v.addr, x.addr, v.typ.Size()) | 1735 memmove(v.addr, x.addr, v.typ.Size()) |
1746 } | 1736 } |
1747 | 1737 |
1748 // Set sets v to the value x. | 1738 // Set sets v to the value x. |
1749 func (v *structValue) SetValue(x Value) { | 1739 func (v *structValue) SetValue(x Value) { |
1750 » v.Set(x.kindPanic(Struct).(*structValue)) | 1740 » v.Set(x.panicIfNot(Struct).(*structValue)) |
1751 } | 1741 } |
1752 | 1742 |
1753 // Field returns the i'th field of the struct. | 1743 // Field returns the i'th field of the struct. |
1754 func (v *structValue) Field(i int) Value { | 1744 func (v *structValue) Field(i int) Value { |
1755 t := v.typ | 1745 t := v.typ |
1756 if i < 0 || i >= t.NumField() { | 1746 if i < 0 || i >= t.NumField() { |
1757 panic("reflect: Field index out of range") | 1747 panic("reflect: Field index out of range") |
1758 } | 1748 } |
1759 f := t.Field(i) | 1749 f := t.Field(i) |
1760 flag := v.flag | 1750 flag := v.flag |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1829 return Value{&chanValue{v}} | 1819 return Value{&chanValue{v}} |
1830 case Float32, Float64: | 1820 case Float32, Float64: |
1831 return Value{&floatValue{v}} | 1821 return Value{&floatValue{v}} |
1832 case Func: | 1822 case Func: |
1833 return Value{&funcValue{value: v}} | 1823 return Value{&funcValue{value: v}} |
1834 case Complex64, Complex128: | 1824 case Complex64, Complex128: |
1835 return Value{&complexValue{v}} | 1825 return Value{&complexValue{v}} |
1836 case Int, Int8, Int16, Int32, Int64: | 1826 case Int, Int8, Int16, Int32, Int64: |
1837 return Value{&intValue{v}} | 1827 return Value{&intValue{v}} |
1838 case Interface: | 1828 case Interface: |
1839 » » return Value{&InterfaceValue{v}} | 1829 » » return Value{&interfaceValue{v}} |
1840 case Map: | 1830 case Map: |
1841 return Value{&mapValue{v}} | 1831 return Value{&mapValue{v}} |
1842 case Ptr: | 1832 case Ptr: |
1843 return Value{&ptrValue{v}} | 1833 return Value{&ptrValue{v}} |
1844 case Slice: | 1834 case Slice: |
1845 return Value{&sliceValue{v}} | 1835 return Value{&sliceValue{v}} |
1846 case String: | 1836 case String: |
1847 return Value{&stringValue{v}} | 1837 return Value{&stringValue{v}} |
1848 case Struct: | 1838 case Struct: |
1849 return Value{&structValue{v}} | 1839 return Value{&structValue{v}} |
1850 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: | 1840 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: |
1851 return Value{&uintValue{v}} | 1841 return Value{&uintValue{v}} |
1852 case UnsafePointer: | 1842 case UnsafePointer: |
1853 return Value{&unsafePointerValue{v}} | 1843 return Value{&unsafePointerValue{v}} |
1854 } | 1844 } |
1855 panic("newValue" + typ.String()) | 1845 panic("newValue" + typ.String()) |
1856 } | 1846 } |
1857 | 1847 |
1858 // MakeZero returns a zero Value for the specified Type. | 1848 // Zero returns a Value representing a zero value for the specified type. |
niemeyer
2011/04/04 13:52:35
More confusion. Now the zero Value is actually the
rsc
2011/04/05 16:29:45
Thanks, this one is wrong. Changed.
// MakeZero
| |
1859 func MakeZero(typ Type) Value { | 1849 // The result is different from the zero value of the Value struct, |
1850 // which represents no value at all. | |
1851 // For example, Zero(Typeof(42)) returns a Value with Kind Int and value 0. | |
1852 func Zero(typ Type) Value { | |
1860 if typ == nil { | 1853 if typ == nil { |
1861 » » panic("reflect: MakeZero(nil)") | 1854 » » panic("reflect: Zero(nil)") |
1862 } | 1855 } |
1863 return newValue(typ, addr(unsafe.New(typ)), canSet|canAddr|canStore) | 1856 return newValue(typ, addr(unsafe.New(typ)), canSet|canAddr|canStore) |
1864 } | 1857 } |
LEFT | RIGHT |