struct.go
func (cache *structTypeCache) lookup(t reflect.Type) (s *structType) {
	cache.mutex.RLock()
	s = cache.store[t]
	cache.mutex.RUnlock()

	if s == nil {
		// There's a race confition here where this value may be generated
		// multiple times.
		// The impact in practice is really small as it's unlikely to happen
		// often, we take the approach of keeping the logic simple and avoid
		// a more complex synchronization logic required to solve this edge
		// case.
		s = newStructType(t, map[reflect.Type]*structType{})
		cache.mutex.Lock()
		cache.store[t] = s
		cache.mutex.Unlock()
	}

	return
}
func (cache *structTypeCache) lookup(t reflect.Type) (s *structType) {
	cache.mutex.RLock()
	s = cache.store[t]
	cache.mutex.RUnlock()

	if s == nil {
		// There's a race confition here where this value may be generated
		// multiple times.
		// The impact in practice is really small as it's unlikely to happen
		// often, we take the approach of keeping the logic simple and avoid
		// a more complex synchronization logic required to solve this edge
		// case.
		s = newStructType(t, map[reflect.Type]*structType{})
		cache.mutex.Lock()
		cache.store[t] = s
		cache.mutex.Unlock()
	}

	return
}
// lookup takes a Go type as argument and returns the matching structType value,
// potentially creating it if it didn't already exist.
// This method is safe to call from multiple goroutines.