이동에 대해

15868 단어 gotdd
Kodumaro의 텍스트입니다.



아웃플랭킹



Go에 대한 나의 첫인상은 매우 잘못되었습니다. 나는 PythonNode.js 관점에서 Go를 측면에 배치했는데 매우 실망했습니다. 열린 마음과 닫힌 마음으로 시스템 리소스에 액세스할 수 있는 강력한 도구를 제공하는 언어를 사용하려고 하면 결과가 실망스럽습니다.

Go가 C++Objective-C에 더 가깝다는 것을 이해하자마자 Go가 멋지고 강력하며 재미있는 프로그래밍 언어라는 것을 깨달았습니다.

당시 한 친구가 Go 포인터를 읽기 전용 매개변수에 대한 읽기-쓰기 매개변수로 설명하려 했지만 헛수고였습니다. 그가 단순히 "C에서와 같은 포인터"라고 말했다면 즉시 이해할 것입니다.

Go에 대한 나의 반대는 Alphabet이 바퀴를 그렇게 어렵게 재현하지 않았을 수도 있고 ValaC♯과 같이 잘 테스트된 다른 플랫폼을 활용할 수 있다는 것입니다. (Linus Tovarlds disagrees에도 불구하고) 부드러운 학습 곡선으로 많은 신 프로그래머를 유혹할 것입니다.

인터페이스



Go에서 interfaces은 Scala의 structural types처럼 보입니다.

반면에 structsObjective-C @interface s과 매우 유사합니다.

인터페이스와 일치하는 구조체의 인스턴스도 구조 유형과 마찬가지로 인터페이스의 인스턴스입니다.

샘플을 위해 다음 인터페이스를 사용하십시오.

type Person interface {
  FirstName() string
  LastName() string
  FullName() string
  Birth() time.Time
}


구조체를 정의한 경우:

type personType struct {
  firstName, lastName string
  birth               time.Time
}


그런 다음 Person의 모든 기능이 personType에 대해 구현됩니다.

func (p personType) FirstName() string {
  return p.firstName
}

func (p personType) LastName() string {
  return p.lastName
}

func (p personType) FullName() string {
  return strings.Trim(fmt.Sprintf("%v %v", p.firstName, p.lastName), " ")
}

func (p personType) Birth() time.Time {
  return p.birth
}


그런 다음 personTypePerson로 반환할 수 있습니다.

func NewPerson(firstName, lastName string, birth time.Time) Person {
  return personType{firstName, lastName, birth}
}


단위 테스트



테스트를 위해 Go에는 사용하기 매우 쉬운 내장testing 라이브러리가 있습니다.

매우 장황하지만 간단한 예는 다음과 같습니다.

func TestPerson(t *testing.T) {
  timeForm := "2006-01-02"
  birth, _ := time.Parse(timeForm, "2017-06-12")
  p := NewPerson("John", "Doe", birth)

  t.Run("primary methods", func(t *testing.T) {
    t.Run("FirstName", func(t *test.T) {
      if got := p.FirstName(); got != "John" {
        t.Fatalf("expected John, got %v", got)
      }
    })

    t.Run("LastName", func(t *test.T) {
      if got := p.LastName(); got != "Doe" {
        t.Fatalf("expected Doe, got %v", got)
      }
    })

    t.Run("Birth", func(t *test.T) {
      expected, _ := time.Parse(timeForm, "2017-02-12")
      if got := p.Birth(); got != expected {
        t.Fatalf("expected %v, got %v", expected, got)
      }
    })
  })

  t.Run("secondary methods", func(t *test.T) {
    t.Run("FullName", func(t *test.T) {
      if got := p.FullName(); got != "John Doe" {
        t.Fatalf("expected John Doe, got %v", got)
      }
    })
  })
}


대부분의 경우 충분합니다.

Go 시간 형식을 이해하려면: Format a time or date .

예외 잡기



Go의 예외 포착 패턴은 잘못될 수 있는 모든 함수에 대한 두 번째 인수로 오류를 반환합니다.

위의 샘플에서 다음 행을 찾을 수 있습니다.

birth, _ := time.Parse(timeForm, "2017-06-12")


밑줄( _ )은 예외가 삭제되었음을 의미합니다. 예외를 처리하려면 다음과 같이 할 수 있습니다.

birth, err := time.Parse(timeForm, "2017-06-12")
if err != nil {
  // Deal with the exception
  ...
}


Go가 예외를 던질 수 있는 또 다른 방법은 공황 발작입니다. panic() 함수를 호출하면 됩니다.

이러한 종류의 예외를 포착하는 유일한 방법은 recover() 블록 내에서 defer를 호출하는 것입니다.

예외를 잡아서 쓰기 가능한 채널( chan 또는 chan<- )을 통해 반환할 수 있습니다.

다음과 같은 냄새가 난다:

func DoSomethingDangerous(res chan<- error) {
  defer res <- recover()

  // Do somenthing that can raise a panic attack.
  ...
}


후기



몇 가지 유용한 리소스:
  • A Tour of Go
  • An Introduction to Programming in Go
  • The Go Blog
  • Going Go Programming (연결할 수 없는 것처럼 보임)
  • The Go Playground
  • 좋은 웹페이지 즐겨찾기