mirror of https://github.com/golang/go.git
go/types: fix a type instantiation issue, added slices.go2 example
Change-Id: If020572762039adf10973bccd072005084e17e4e
This commit is contained in:
parent
c4a20af9f1
commit
d03ba9f74c
|
|
@ -0,0 +1,63 @@
|
|||
// Package slices implements various slice algorithms.
|
||||
package slices
|
||||
|
||||
// Map turns a []T1 to a []T2 using a mapping function.
|
||||
func Map(type T1, T2)(s []T1, f func(T1) T2) []T2 {
|
||||
r := make([]T2, len(s))
|
||||
for i, v := range s {
|
||||
r[i] = f(v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Reduce reduces a []T1 to a single value using a reduction function.
|
||||
func Reduce(type T1, T2)(s []T1, initializer T2, f func(T2, T1) T2) T2 {
|
||||
r := initializer
|
||||
for _, v := range s {
|
||||
r = f(r, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Filter filters values from a slice using a filter function.
|
||||
func Filter(type T)(s []T, f func(T) bool) []T {
|
||||
var r []T
|
||||
for _, v := range s {
|
||||
if f(v) {
|
||||
r = append(r, v)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Example uses
|
||||
|
||||
func limiter(x int) byte {
|
||||
switch {
|
||||
case x < 0:
|
||||
return 0
|
||||
default:
|
||||
return byte(x)
|
||||
case x > 255:
|
||||
return 255
|
||||
}
|
||||
}
|
||||
|
||||
var input = []int{-4, 68954, 7, 44, 0, -555, 6945}
|
||||
var limited1 = Map(int, byte)(input, limiter)
|
||||
var limited2 = Map(input, limiter) // using type inference
|
||||
|
||||
func reducer(x float64, y int) float64 {
|
||||
return x + float64(y)
|
||||
}
|
||||
|
||||
var reduced1 = Reduce(int, float64)(input, 0, reducer)
|
||||
var reduced2 = Reduce(input, 1.0, reducer) // using type inference
|
||||
|
||||
func filter(x int) bool {
|
||||
return x&1 != 0
|
||||
}
|
||||
|
||||
var filtered1 = Filter(int)(input, filter)
|
||||
var filtered2 = Filter(input, filter) // using type inference
|
||||
|
||||
|
|
@ -1,8 +1,18 @@
|
|||
package p
|
||||
|
||||
func Ranger(type T)() (*Receiver(T)) {
|
||||
//return &Receiver(T){} // TODO(gri) make this work
|
||||
return nil
|
||||
func Reduce(type T1, T2)(s []T1, initializer T2, f func(T2, T1) T2) T2 {
|
||||
r := initializer
|
||||
for _, v := range s {
|
||||
r = f(r, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type Receiver(type T) struct {}
|
||||
func reducer(float64, int) float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var _ = Reduce([]int{}, 1.0, reducer)
|
||||
|
||||
// TODO(gri) investigate - seems like type inference should accept 1 here
|
||||
// var _ = Reduce([]int{}, 1, reducer)
|
||||
|
|
|
|||
|
|
@ -143,10 +143,14 @@ func (check *Checker) definedType(e ast.Expr, def *Named) (T Type) {
|
|||
}
|
||||
|
||||
// instantiatedType is like typ but it ensures that a Parametrized type is
|
||||
// fully instantiated.
|
||||
// fully instantiated if all type parameters are known.
|
||||
// (When we type-check a parameterized function body, parameterized types
|
||||
// whose type parameters are incoming parameters cannot be instantiated.)
|
||||
func (check *Checker) instantiatedType(e ast.Expr) Type {
|
||||
typ := check.typ(e)
|
||||
if ptyp, _ := typ.(*Parameterized); ptyp != nil {
|
||||
// A parameterized type where all type arguments are known
|
||||
// (i.e., not type parameters themselves) can be instantiated.
|
||||
if ptyp, _ := typ.(*Parameterized); ptyp != nil && !isParameterized(ptyp) {
|
||||
typ = check.inst(ptyp.tname, ptyp.targs)
|
||||
// TODO(gri) can this ever be nil? comment.
|
||||
if typ == nil {
|
||||
|
|
|
|||
Loading…
Reference in New Issue