指针

函数返回值

场景1:函数的返回值是子结构体

函数的返回值是基础结构体,使用新结构体的指针形式实现基础结构体,若函数返回新结构体那么只能返回新结构的指针

  1. package main
  2. import "fmt"
  3. type CustomError struct {
  4. s string
  5. }
  6. func (e *CustomError)Error() string {
  7. return e.s
  8. }
  9. func New(mes string) error {
  10. customError := CustomError{ s: mes }
  11. return &customError // 返回结构体的指针
  12. }
  13. func main() {
  14. e := New("Some thing happen")
  15. fmt.Println(e)
  16. }

场景2: 类型断言

子类型使用指针实现基础类型

  1. package main
  2. import "fmt"
  3. // HttpError struct
  4. type HttpError struct {
  5. message string
  6. method string
  7. status int
  8. }
  9. func (httpError *HttpError) Error() string{
  10. return fmt.Sprintf("The method func %v, method status %v, method message %v", httpError.method, httpError.status, httpError.message)
  11. }
  12. func getEmail(userID string) (string, error) {
  13. return "", &HttpError{
  14. message: "Something error",
  15. method: "Get",
  16. status: 403,
  17. }
  18. }
  19. func main() {
  20. _, err := getEmail("12")
  21. fmt.Println(err)
  22. if err != nil {
  23. errVal := err.(*HttpError) //断言至基础类型的指针形式
  24. fmt.Println(errVal.status)
  25. }
  26. }

场景3:接口动态类型断言

无论是接口方法接收类型是指针还是普通都可以使用 i.(Type) 获取接口的动态结构体

  1. package main
  2. import "fmt"
  3. // UserSessionState ...
  4. type UserSessionState interface {
  5. error
  6. isLoggedIn() bool
  7. getSessionId() int
  8. }
  9. // UnauthorizedError ...
  10. type UnauthorizedError struct{
  11. UserID int
  12. SessionID int
  13. }
  14. func (err *UnauthorizedError)isLoggedIn() bool {
  15. return err.SessionID != 0
  16. }
  17. func (err *UnauthorizedError)getSessionId() int{
  18. return err.SessionID
  19. }
  20. func (err *UnauthorizedError)Error() string{
  21. return fmt.Sprintf("User with id %v cannot perform current ation", err.SessionID)
  22. }
  23. func validateUser(userID int) error {
  24. return &UnauthorizedError{userID, 12312}
  25. }
  26. func main() {
  27. err := validateUser(123)
  28. if err != nil {
  29. fmt.Println(err)
  30. if errVal, ok := err.(UserSessionState); ok { // 获取接口的动态类型
  31. fmt.Println("Will cleaning session id ", errVal.getSessionId())
  32. errNestedVal, ok := err.(*UnauthorizedError)
  33. if (ok) {
  34. fmt.Println("Nested val", errNestedVal.UserID)
  35. }
  36. }
  37. } else {
  38. fmt.Println("User is allowed to perform this action")
  39. }
  40. }

断言判断

从channel中读数据

  1. val, ok := <- c

结构体断言

  1. errVal, ok := err.(*HttpError)
  2. 或者
  3. errVal, ok := err.(HttpError)