在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.
 
 
 

221 Zeilen
4.0 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 int64:
  54. return float64(s), true
  55. case int32:
  56. return float64(s), true
  57. case int16:
  58. return float64(s), true
  59. case int8:
  60. return float64(s), true
  61. case int:
  62. return float64(s), true
  63. case string:
  64. v, err := strconv.ParseFloat(s, 64)
  65. if err == nil {
  66. return float64(v), true
  67. } else {
  68. jww.ERROR.Printf("Unable to Cast %#v to float", i)
  69. jww.ERROR.Println(err)
  70. }
  71. default:
  72. jww.ERROR.Printf("Unable to Cast %#v to float", i)
  73. }
  74. return 0.0, false
  75. }
  76. func ToIntE(i interface{}) (int, bool) {
  77. switch s := i.(type) {
  78. case int:
  79. return s, true
  80. case int64:
  81. return int(s), true
  82. case int32:
  83. return int(s), true
  84. case int16:
  85. return int(s), true
  86. case int8:
  87. return int(s), true
  88. case string:
  89. v, err := strconv.ParseInt(s, 0, 0)
  90. if err == nil {
  91. return int(v), true
  92. } else {
  93. jww.ERROR.Printf("Unable to Cast %#v to int", i)
  94. jww.ERROR.Println(err)
  95. }
  96. case float64:
  97. return int(s), true
  98. case bool:
  99. if bool(s) {
  100. return 1, true
  101. } else {
  102. return 0, true
  103. }
  104. case nil:
  105. return 0, true
  106. default:
  107. jww.ERROR.Printf("Unable to Cast %#v to int", i)
  108. }
  109. return 0, false
  110. }
  111. func ToStringE(i interface{}) (string, bool) {
  112. switch s := i.(type) {
  113. case string:
  114. return s, true
  115. case float64:
  116. return strconv.FormatFloat(i.(float64), 'f', -1, 64), true
  117. case int:
  118. return strconv.FormatInt(int64(i.(int)), 10), true
  119. case []byte:
  120. return string(s), true
  121. case nil:
  122. return "", true
  123. default:
  124. jww.ERROR.Printf("Unable to Cast %#v to string", i)
  125. }
  126. return "", false
  127. }
  128. func ToStringMapStringE(i interface{}) (map[string]string, bool) {
  129. var m = map[string]string{}
  130. switch v := i.(type) {
  131. case map[interface{}]interface{}:
  132. for k, val := range v {
  133. m[ToString(k)] = ToString(val)
  134. }
  135. case map[string]string:
  136. return v, true
  137. default:
  138. return m, false
  139. }
  140. return m, true
  141. }
  142. func ToStringMapE(i interface{}) (map[string]interface{}, bool) {
  143. var m = map[string]interface{}{}
  144. switch v := i.(type) {
  145. case map[interface{}]interface{}:
  146. for k, val := range v {
  147. m[ToString(k)] = val
  148. }
  149. case map[string]interface{}:
  150. return v, true
  151. default:
  152. return m, false
  153. }
  154. return m, true
  155. }
  156. func ToStringSliceE(i interface{}) ([]string, bool) {
  157. var a []string
  158. switch v := i.(type) {
  159. case []interface{}:
  160. for _, u := range v {
  161. a = append(a, ToString(u))
  162. }
  163. case []string:
  164. return v, true
  165. default:
  166. return a, false
  167. }
  168. return a, true
  169. }
  170. func StringToDate(s string) (time.Time, error) {
  171. return parseDateWith(s, []string{
  172. time.RFC3339,
  173. "2006-01-02T15:04:05", // iso8601 without timezone
  174. time.RFC1123Z,
  175. time.RFC1123,
  176. time.RFC822Z,
  177. time.RFC822,
  178. time.ANSIC,
  179. time.UnixDate,
  180. time.RubyDate,
  181. "2006-01-02 15:04:05Z07:00",
  182. "02 Jan 06 15:04 MST",
  183. "2006-01-02",
  184. "02 Jan 2006",
  185. })
  186. }
  187. func parseDateWith(s string, dates []string) (d time.Time, e error) {
  188. for _, dateType := range dates {
  189. if d, e = time.Parse(dateType, s); e == nil {
  190. return
  191. }
  192. }
  193. return d, errors.New(fmt.Sprintf("Unable to parse date: %s", s))
  194. }