func (s *Section) GetKey(name string) (*Key, error) {
	if s.f.BlockMode {
		s.f.lock.RLock()
	}
	if s.f.options.Insensitive {
		name = strings.ToLower(name)
	}
	key := s.keys[name]
	if s.f.BlockMode {
		s.f.lock.RUnlock()
	}
	if key == nil {
		sname := s.name
		for {
			if i := strings.LastIndex(sname, "."); i > -1 {
				sname = sname[:i]
				sec, err := s.f.GetSection(sname)
				if err != nil {
					continue
				}
				return sec.GetKey(name)
			} else {
				break
			}
		}
		return nil, fmt.Errorf("error when getting key of section '%s': key '%s' not exists", s.name, name)
	}
	return key, nil
}
GetKey returns key in section by given name.
package ini
import (
	"errors"
	"fmt"
	"strings"
)
type Section struct {
	f        *File
	Comment  string
	name     string
	keys     map[string]*Key
	keyList  []string
	keysHash map[string]string
	isRawSection bool
	rawBody      string
}
func newSection(f *File, name string) *Section {
	return &Section{
		f:        f,
		name:     name,
		keys:     make(map[string]*Key),
		keyList:  make([]string, 0, 10),
		keysHash: make(map[string]string),
	}
}
func (s *Section) Name() string {
	return s.name
}
func (s *Section) Body() string {
	return strings.TrimSpace(s.rawBody)
}
func (s *Section) NewKey(name, val string) (*Key, error) {
	if len(name) == 0 {
		return nil, errors.New("error creating new key: empty key name")
	} else if s.f.options.Insensitive {
		name = strings.ToLower(name)
	}
	if s.f.BlockMode {
		s.f.lock.Lock()
		defer s.f.lock.Unlock()
	}
	if inSlice(name, s.keyList) {
		if s.f.options.AllowShadows {
			if err := s.keys[name].addShadow(val); err != nil {
				return nil, err
			}
		} else {
			s.keys[name].value = val
		}
		return s.keys[name], nil
	}
	s.keyList = append(s.keyList, name)
	s.keys[name] = newKey(s, name, val)
	s.keysHash[name] = val
	return s.keys[name], nil
}
func (s *Section) NewBooleanKey(name string) (*Key, error) {
	key, err := s.NewKey(name, "true")
	if err != nil {
		return nil, err
	}
	key.isBooleanType = true
	return key, nil
}