type Time struct { // sec gives the number of seconds elapsed since // January 1, year 1 00:00:00 UTC. sec int64 // nsec specifies a non-negative nanosecond // offset within the second named by Seconds. // It must be in the range [0, 999999999]. nsec int32 // loc specifies the Location that should be used to // determine the minute, hour, month, day, and year // that correspond to this Time. // The nil location means UTC. // All UTC times are represented with loc==nil, never loc==&utcLoc. loc *Location }
// After reports whether the time instant t is after u. func(t Time)After(u Time)bool { return t.sec > u.sec || t.sec == u.sec && t.nsec > u.nsec }
// Before reports whether the time instant t is before u. func(t Time)Before(u Time)bool { return t.sec < u.sec || t.sec == u.sec && t.nsec < u.nsec }
// Equal reports whether t and u represent the same time instant. // Two times can be equal even if they are in different locations. // For example, 6:00 +0200 CEST and 4:00 UTC are Equal. // Do not use == with Time values. func(t Time)Equal(u Time)bool { return t.sec == u.sec && t.nsec == u.nsec }
func(t Time)Sub(u Time)Duration { d := Duration(t.sec-u.sec)*Second + Duration(t.nsec-u.nsec) // Check for overflow or underflow. switch { case u.Add(d).Equal(t): return d // d is correct case t.Before(u): return minDuration // t - u is negative out of range default: return maxDuration // t - u is positive out of range }
// The Timer type represents a single event. // When the Timer expires, the current time will be sent on C, // unless the Timer was created by AfterFunc. // A Timer must be created with NewTimer or AfterFunc. type Timer struct { C <-chan Time r runtimeTimer }
// NewTimer creates a new Timer that will send // the current time on its channel after at least duration d. funcNewTimer(d Duration) * Timer { c := make(chan Time, 1) t := &Timer{ C: c, r: runtimeTimer{ when: when(d), f: sendTime, arg: c, }, } startTimer(&t.r) return t }
funcAfterFunc(d Duration, f func()) * Timer { t := &Timer{ r: runtimeTimer{ when: when(d), f: goFunc, arg: f, }, } startTimer(&t.r) return t }
func(t * Timer)Reset(d Duration)bool { if t.r.f == nil { panic("time: Reset called on uninitialized Timer") } w := when(d) active := stopTimer(&t.r) t.r.when = w startTimer(&t.r) return active }
After函数
1 2 3 4 5 6 7 8 9
// After waits for the duration to elapse and then sends the current time // on the returned channel. // It is equivalent to NewTimer(d).C. // The underlying Timer is not recovered by the garbage collector // until the timer fires. If efficiency is a concern, use NewTimer // instead and call Timer.Stop if the timer is no longer needed. funcAfter(d Duration) <-chanTime { return NewTimer(d).C }
// Stop prevents the Timer from firing. // It returns true if the call stops the timer, false if the timer has already // expired or been stopped. // Stop does not close the channel, to prevent a read from the channel succeeding // incorrectly. // // To prevent a timer created with NewTimer from firing after a call to Stop, // check the return value and drain the channel. // For example, assuming the program has not received from t.C already: // if !t.Stop() { // <-t.C // } // This cannot be done concurrent to other receives from the Timer's // channel. // // For a timer created with AfterFunc(d, f), if t.Stop returns false, then the timer // has already expired and the function f has been started in its own goroutine; // Stop does not wait for f to complete before returning. // If the caller needs to know whether f is completed, it must coordinate // with f explicitly. func(t * Timer)Stop()bool { if t.r.f == nil { panic("time: Stop called on uninitialized Timer") } return stopTimer(&t.r) }
var x float64 = 3.4 v := reflect.ValueOf(x) fmt.Println("type:", v.Type()) fmt.Println("kind is float64:", v.Kind() == reflect.Float64) fmt.Println("value:", v.Float())
var x float64 = 3.4 v := reflect.ValueOf(x) v.SetFLoat(7.1)
如果这行代码能够成功执行,它不会更新 x ,虽然看起来变量 v 是根据 x 创建的。相反,它会更新 x 存在于 反射对象 v 内部的一个拷贝,而变量 x 本身完全不受影响。这会造成迷惑,并且没有任何意义,所以是不合法的。“可写性”就是为了避免这个问题而设计的。 上面的代码中,我们把变量 x 的一个拷贝传递给函数,因此不期望它会改变 x 的值。如果期望函数 f 能够修改变量 x,我们必须传递 x 的地址(即指向 x 的指针)给函数 f,如下:
type T struct { A int B string } t := T{23, "skidoo"} s := reflect.ValueOf(&t).Elem() typeOfT := s.Type() for i := 0; i < s.NumField(); i++ { f := s.Field(i) fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface()) }
上面这段代码的输出如下:
1 2
0: A int = 23 1: B string = skidoo
这里有一点需要指出:变量 T 的字段都是首字母大写的(暴露到外部),因为struct中只有暴露到外部的字段才是“可写的”。 由于变量 s 包含一个“可写的”反射对象,我们可以修改结构体的字段:
1 2 3
s.Field(0).SetInt(77) s.Field(1).SetString("Sunset Strip") fmt.Println("t is now", t)