在Go中轻松安全地从一种数据类型转换为另一种数据类型
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

205 Zeilen
3.7 KiB

  1. // Copyright © 2014 Steve Francia <spf@spf13.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. package cast
  6. import (
  7. "errors"
  8. "fmt"
  9. "strconv"
  10. "time"
  11. jww "github.com/spf13/jwalterweatherman"
  12. )
  13. func ToTimeE(i interface{}) (tim time.Time, ok bool) {
  14. switch s := i.(type) {
  15. case time.Time:
  16. return s, true
  17. case string:
  18. d, e := StringToDate(s)
  19. if e == nil {
  20. return d, true
  21. }
  22. jww.ERROR.Println("Could not parse Date/Time format:", e)
  23. return time.Time{}, false
  24. default:
  25. jww.ERROR.Printf("Unable to Cast %#v to Time", i)
  26. return time.Time{}, false
  27. }
  28. return time.Time{}, false
  29. }
  30. func ToBoolE(i interface{}) (bool, bool) {
  31. switch b := i.(type) {
  32. case bool:
  33. return b, true
  34. case nil:
  35. return false, true
  36. case int:
  37. if i.(int) > 0 {
  38. return true, true
  39. }
  40. return false, true
  41. default:
  42. return false, false
  43. jww.ERROR.Printf("Unable to Cast %#v to bool", i)
  44. }
  45. return false, false
  46. }
  47. func ToFloat64E(i interface{}) (float64, bool) {
  48. switch s := i.(type) {
  49. case float64:
  50. return s, true
  51. case float32:
  52. return float64(s), true
  53. case string:
  54. v, err := strconv.ParseFloat(s, 64)
  55. if err == nil {
  56. return float64(v), true
  57. } else {
  58. jww.ERROR.Printf("Unable to Cast %#v to float", i)
  59. jww.ERROR.Println(err)
  60. }
  61. default:
  62. jww.ERROR.Printf("Unable to Cast %#v to float", i)
  63. }
  64. return 0.0, false
  65. }
  66. func ToIntE(i interface{}) (int, bool) {
  67. switch s := i.(type) {
  68. case int:
  69. return s, true
  70. case int64:
  71. return int(s), true
  72. case int32:
  73. return int(s), true
  74. case int16:
  75. return int(s), true
  76. case int8:
  77. return int(s), true
  78. case string:
  79. v, err := strconv.ParseInt(s, 0, 0)
  80. if err == nil {
  81. return int(v), true
  82. } else {
  83. jww.ERROR.Printf("Unable to Cast %#v to int", i)
  84. jww.ERROR.Println(err)
  85. }
  86. case float64:
  87. return int(s), true
  88. case bool:
  89. if bool(s) {
  90. return 1, true
  91. } else {
  92. return 0, true
  93. }
  94. case nil:
  95. return 0, true
  96. default:
  97. jww.ERROR.Printf("Unable to Cast %#v to int", i)
  98. }
  99. return 0, false
  100. }
  101. func ToStringE(i interface{}) (string, bool) {
  102. switch s := i.(type) {
  103. case string:
  104. return s, true
  105. case float64:
  106. return strconv.FormatFloat(i.(float64), 'f', -1, 64), true
  107. case int:
  108. return strconv.FormatInt(int64(i.(int)), 10), true
  109. case []byte:
  110. return string(s), true
  111. case nil:
  112. return "", true
  113. default:
  114. jww.ERROR.Printf("Unable to Cast %#v to string", i)
  115. }
  116. return "", false
  117. }
  118. func ToStringMapStringE(i interface{}) (map[string]string, bool) {
  119. var m = map[string]string{}
  120. switch v := i.(type) {
  121. case map[interface{}]interface{}:
  122. for k, val := range v {
  123. m[ToString(k)] = ToString(val)
  124. }
  125. default:
  126. return m, false
  127. }
  128. return m, true
  129. }
  130. func ToStringMapE(i interface{}) (map[string]interface{}, bool) {
  131. var m = map[string]interface{}{}
  132. switch v := i.(type) {
  133. case map[interface{}]interface{}:
  134. for k, val := range v {
  135. m[ToString(k)] = val
  136. }
  137. default:
  138. return m, false
  139. }
  140. return m, true
  141. }
  142. func ToStringSliceE(i interface{}) ([]string, bool) {
  143. var a []string
  144. switch v := i.(type) {
  145. case []interface{}:
  146. for _, u := range v {
  147. a = append(a, ToString(u))
  148. }
  149. default:
  150. return a, false
  151. }
  152. return a, true
  153. }
  154. func StringToDate(s string) (time.Time, error) {
  155. return parseDateWith(s, []string{
  156. time.RFC3339,
  157. "2006-01-02T15:04:05", // iso8601 without timezone
  158. time.RFC1123Z,
  159. time.RFC1123,
  160. time.RFC822Z,
  161. time.RFC822,
  162. time.ANSIC,
  163. time.UnixDate,
  164. time.RubyDate,
  165. "2006-01-02 15:04:05Z07:00",
  166. "02 Jan 06 15:04 MST",
  167. "2006-01-02",
  168. "02 Jan 2006",
  169. })
  170. }
  171. func parseDateWith(s string, dates []string) (d time.Time, e error) {
  172. for _, dateType := range dates {
  173. if d, e = time.Parse(dateType, s); e == nil {
  174. return
  175. }
  176. }
  177. return d, errors.New(fmt.Sprintf("Unable to parse date: %s", s))
  178. }