Go를 만지는 1.18.

18996 단어 Gotech
1.18의 눈동자를 가볍게 터치하는 기능generics와fuzz
  • https://go.dev/doc/tutorial/generics
  • https://go.dev/doc/tutorial/fuzz
  • 차리다

  • Go만 1.18로 업데이트
  • brewbrew install go라면
  • 공식
  • https://go.dev/doc/install
  • generics


    개요

  • 한마디로 총칭형
  • 실제 사용 전에 모델 번호 불확정
  • 고 특유의 것이 아니어서 새롭지 않다
  • 시험해 보다

  • int와flat의 유형이 다른 경우에만 같은 함수를 각각 생성합니다
    main.go
    // SumInts adds together the values of m.
    func SumInts(m map[string]int64) int64 {
        var s int64
        for _, v := range m {
            s += v
        }
        return s
    }
    
    // SumFloats adds together the values of m.
    func SumFloats(m map[string]float64) float64 {
        var s float64
        for _, v := range m {
            s += v
        }
        return s
    }
    
    func main() {
        // Initialize a map for the integer values
        ints := map[string]int64{
            "first":  34,
            "second": 12,
        }
    
        // Initialize a map for the float values
        floats := map[string]float64{
            "first":  35.98,
            "second": 26.99,
        }
    
        fmt.Printf("Non-Generic Sums: %v and %v\n",
            SumInts(ints),
            SumFloats(floats))
    }
    
  • generics로 유니버설 가능
    main.go
    // SumIntsOrFloats sums the values of map m. It supports both int64 and float64
    // as types for map values.
    func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
        var s V
        for _, v := range m {
            s += v
        }
        return s
    }
    
  • fuzz


    개요

  • 이른fuzz테스트
  • 이상 시스템의 테스트를 자동화 확인
  • 시험해 보다

  • 문자열을 상반시키는 함수 만들기
    main.go
    func Reverse(s string) (string, error) {
        b := []byte(s)
        for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
        	b[i], b[j] = b[j], b[i]
        }
        return string(b)
    }
    
    func main() {
        input := "The quick brown fox jumped over the lazy dog"
        rev := Reverse(input)
        doubleRev := Reverse(rev)
        fmt.Printf("original: %q\n", input)
        fmt.Printf("reversed: %q\n", rev)
        fmt.Printf("reversed again: %q\n", doubleRev)
    }
    
  • 비고
  • main 함수에 The quick brown fox jumped over the lazy dog가 있다고 생각하면 모든 자모를 사용하는 유명한 언어 게임인 것 같다
  • https://ja.wikipedia.org/wiki/빵집
  • go test -fuzz=Fuzz의 fuzing
  • 바이트로 문자열을 반전시키면 멀티바이트가 잘못되므로rune처리를 사용합니다
  • https://go.dev/blog/strings
  • main.go
    func Reverse(s string) (string, error) {
        r := []rune(s)
        for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
        	r[i], r[j] = r[j], r[i]
        }
        return string(r)
    }
    
  • 비고
  • 테스트가 fail인 경우fuzz 로고를 제거하면 같은 테스트 용례를 실행할 수 있습니다
  • 테스트 용례는testdata/fuz/${FuzTestName}에 저장

  • 테스트가 t.Logf()에서 fail을 진행하거나 v 옵션을 추가했을 때만 표준 출력
  • 을 할 수 있습니다
  • 다시 go test -fuzz=Fuzz
  • UTF-8 이외의 문자를 입력하면 오류가 발생하므로 포함된 유효성 검사
    main.go
    func Reverse(s string) (string, error) {
        if !utf8.ValidString(s) {
        	return s, errors.New("input is not valid UTF-8")
        }
        r := []rune(s)
        for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
        	r[i], r[j] = r[j], r[i]
        }
        return string(r), nil
    }
    
  • 비고
  • go test -run ${FuzzTestName}/${filename}에서 특정 파일의 테스트 용례를 실행할 수 있음
  • 다시 go test -fuzz=Fuzz
  • fail을 진행하지 않았지만 처리를 멈출 수 없음
  • 명확하게 정지하지 않으면 fail까지 fuzzing을 실행합니다
  • -fuzztime 30s처럼 시간 지정
    ❯ go test -fuzz=Fuzz -fuzztime 5s
    fuzz: elapsed: 0s, gathering baseline coverage: 0/43 completed
    fuzz: elapsed: 0s, gathering baseline coverage: 43/43 completed, now fuzzing with 12 workers
    fuzz: elapsed: 3s, execs: 757072 (252347/sec), new interesting: 2 (total: 45)
    fuzz: elapsed: 5s, execs: 1242894 (228431/sec), new interesting: 2 (total: 45)
    PASS
    ok  	example/fuzz	5.251s
    
  • 감상


    이번 Go의 가장 큰 업데이트는 주요 2가지 기능을 터치했지만 실제 제품은 당장 전투력으로 처리할 수 있는 수준이라고 느꼈다.
    Go 공식의 강좌는 간단하면서도 좋다.새로운 기능이 있으면 다시 만지고 싶어요.

    좋은 웹페이지 즐겨찾기