func (k *Key) MustFloat64(defaultVal ...float64) float64 {
	val, err := k.Float64()
	if len(defaultVal) > 0 && err != nil {
		k.value = strconv.FormatFloat(defaultVal[0], 'f', -1, 64)
		return defaultVal[0]
	}
	return val
}
MustFloat64 always returns value without error,
it returns 0.0 if error occurs.
package ini
import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"time"
)
type Key struct {
	s               *Section
	name            string
	value           string
	isAutoIncrement bool
	isBooleanType   bool
	isShadow bool
	shadows  []*Key
	Comment string
}
func newKey(s *Section, name, val string) *Key {
	return &Key{
		s:     s,
		name:  name,
		value: val,
	}
}
func (k *Key) addShadow(val string) error {
	if k.isShadow {
		return errors.New("cannot add shadow to another shadow key")
	} else if k.isAutoIncrement || k.isBooleanType {
		return errors.New("cannot add shadow to auto-increment or boolean key")
	}
	shadow := newKey(k.s, k.name, val)
	shadow.isShadow = true
	k.shadows = append(k.shadows, shadow)
	return nil
}
func (k *Key) AddShadow(val string) error {
	if !k.s.f.options.AllowShadows {
		return errors.New("shadow key is not allowed")
	}
	return k.addShadow(val)
}
type ValueMapper func(string) string
func (k *Key) Name() string {
	return k.name
}
func (k *Key) Value() string {
	return k.value
}
func (k *Key) ValueWithShadows() []string {
	if len(k.shadows) == 0 {
		return []string{k.value}
	}
	vals := make([]string, len(k.shadows)+1)
	vals[0] = k.value
	for i := range k.shadows {
		vals[i+1] = k.shadows[i].value
	}
	return vals
}
func (k *Key) transformValue(val string) string {
	if k.s.f.ValueMapper != nil {
		val = k.s.f.ValueMapper(val)
	}
	if !strings.Contains(val, "%") {
		return val
	}
	for i := 0; i < _DEPTH_VALUES; i++ {
		vr := varPattern.FindString(val)
		if len(vr) == 0 {
			break
		}
		noption := strings.TrimLeft(vr, "%(")
		noption = strings.TrimRight(noption, ")s")
		nk, err := k.s.GetKey(noption)
		if err != nil {
			nk, _ = k.s.f.Section("").GetKey(noption)
		}
		val = strings.Replace(val, vr, nk.value, -1)
	}
	return val
}
func (k *Key) String() string {
	return k.transformValue(k.value)
}
func (k *Key) Validate(fn func(string) string) string {
	return fn(k.String())
}
func parseBool(str string) (value bool, err error) {
	switch str {
	case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "y", "ON", "on", "On":
		return true, nil
	case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "n", "OFF", "off", "Off":
		return false, nil
	}
	return false, fmt.Errorf("parsing \"%s\": invalid syntax", str)
}
func (k *Key) Bool() (bool, error) {
	return parseBool(k.String())
}
func (k *Key) Float64() (float64, error) {
	return strconv.ParseFloat(k.String(), 64)
}
func (k *Key) Int() (int, error) {
	return strconv.Atoi(k.String())
}
func (k *Key) Int64() (int64, error) {
	return strconv.ParseInt(k.String(), 10, 64)
}
func (k *Key) Uint() (uint, error) {
	u, e := strconv.ParseUint(k.String(), 10, 64)
	return uint(u), e
}
func (k *Key) Uint64() (uint64, error) {
	return strconv.ParseUint(k.String(), 10, 64)
}
func (k *Key) Duration() (time.Duration, error) {
	return time.ParseDuration(k.String())
}
func (k *Key) TimeFormat(format string) (time.Time, error) {
	return time.Parse(format, k.String())
}
func (k *Key) Time() (time.Time, error) {
	return k.TimeFormat(time.RFC3339)
}
func (k *Key) MustString(defaultVal string) string {
	val := k.String()
	if len(val) == 0 {
		k.value = defaultVal
		return defaultVal
	}
	return val
}
func (k *Key) MustBool(defaultVal ...bool) bool {
	val, err := k.Bool()
	if len(defaultVal) > 0 && err != nil {
		k.value = strconv.FormatBool(defaultVal[0])
		return defaultVal[0]
	}
	return val
}