코드 기반 Go언어 배우기 (기초)

shinychan95·2021년 6월 24일
0

go-with-Go

목록 보기
2/4
post-thumbnail

참고자료

 

변수, 상수, 데이터 타입, 연산자, 조건문, 반복문

package main

import "fmt" // 파일 입출력 관련 표준 라이브러리 패키지

func main() {
    println("Hello World")

    /* 1. Variable */
    var i, j, k int = 1, 2, 3 // mismatch 주의
    var tmp int // 기본값은 0
    v: = 999 // 타입 추론 및 func 내 var 생략

    println(i)
    println(j)
    println(k)
    println(tmp)
    println(v)

    /* 2. Constant */
    const (
        Visa = "Visa"
        Master = "MasterCard"
        Amex = "American Express"
    )

    const (
        Apple = iota // 0
        Grape // 1
        Orange // 2
    )

    println(Visa)
    println(Apple)

    /* 3. Data Type */
    // bool
    // string (immutable)
    // int, int8, int16, int 64
    // uint uint8 uint16 uint32 uint64 uintptr
    // float32 float64 complex64 complex128
    // byte: uint8과 동일하며 바이트 코드에 사용
    // rune: int32과 동일하며 유니코드 코드포인트에 사용한다

    /* 4. String */
    // Raw String Literal. 복수라인에 주로 사용된다.
    rawLiteral: = `아리랑\n
아리랑\n
아라리요`

    // Interpreted String Literal
    interLiteral: = "아리랑아리랑\n아리리요"
        // 아래와 같이 +를 사용하여 두 라인에 걸쳐 사용할 수도 있다.
        // interLiteral := "아리랑아리랑\n" +
        //                 "아리리요"

    fmt.Println(rawLiteral)
    fmt.Println()
    fmt.Println(interLiteral)

    /* 5. Type Conversion */
    var x5 int = 100
    var y5 uint = uint(x5)
    var z5 float32 = float32(y5)
    println(z5, y5)

    str5: = "ABC"
    bytes: = [] byte(str5)
    strCovt: = string(bytes)
    println(bytes, strCovt)

    /* 6. Operator */
    // Pointer op
    var k6 int = 10
    var ptr = & k6 //k의 주소를 할당
    println(ptr)
    println( * ptr) //p가 가리키는 주소에 있는 실제 내용을 출력

    /* 7. if statement */
    i7: = 2
    if i7 == 1 { //같은 라인
        println("One")
    } else if i7 == 2 { //같은 라인
        println("Two")
    } else { //같은 라인
        println("Other")
    }

    // if 문에서 조건식 사용하기 전에 Optional Statement가 가능하다.
    max: = 100
    if v7: = i7 * 2;
    v7 < max {
        println(v7)
    }

    /* 8. Switch statement */
    var name string
    var category = 2

    switch category {
        case 1:
            name = "Paper Book"
        case 2:
            name = "eBook"
        case 3, 4: // 콤마를 통해 복수개의 case 값 적용 가능
            name = "Blog"
        default:
            name = "Other"
    }
    println(name)

    // Expression을 사용한 경우
    // switch x := category << 2; x - 1 {
    //    ...
    // }

    // Go만의 특별한 용법들
    // 1. switch 뒤에 expression이 없을 수 있음
    // 2. case문에 expression을 쓸 수 있음
    // 3. No default fall through (break 없어도 다른 case 문으로 가지 않는다)
    // 4. Type switch

    // 3번의 경우, fallthrough를 명시해주어 다음 case로 넘어갈 수 있고,
    // 4번의 경우, 아래와 같이 활용한다.
    explain: = func(i interface {}) {
        switch t: = i.(type) {
            case bool:
                fmt.Println("I'm a bool")
            case int:
                fmt.Println("I'm an int")
            case string:
                fmt.Println("I'm a string")
            default:
                fmt.Printf("Don't know type %T\n", t)
        }
    }

    explain(name)

    /* 9. for loop statement */
    sum: = 0
    for i: = 1;
    i <= 100;
    i++{ // 괄호 ()를 쓰면 에러가 발생한다.
        sum += i
    }
    println(sum)

    i9: = 1
    for i9 < 100 { // 조건만 작성하여 while처럼 사용할 수 있다.
        i9 *= 2
            //if i9 > 90 {
            //   break
            //}
    }
    println(i9)

    // 무한 루프는 조건 없이 for만 적는다.
    // for {
    //     println("Infinite loop")
    // }

    // for range 문이 가능하다
    names: = [] string {
        "홍길동", "이순신", "강감찬"
    }

    for index, name: = range names {
        println(index, name)
    }

    // 그 외에 break, continue, goto 문이 사용된다.
}

 

함수, 클로저, 컬렉션

package main

import (
    "fmt"
)

/* 익명 함수 관련 내용 추가 */
// 함수 원형 정의
type calculatorNum func(int, int) int
type calculatorStr func(string, string) string

func calNum(f calculatorNum, a int, b int) int {
    result: = f(a, b)
    return result
}

func calStr(f calculatorStr, a string, b string) string {
    sentence: = f(a, b)
    return sentence
}

func main() {
    /* 1. Function */
    msg: = "Hello World"
    say(msg)

    /* 2. Pass By Reference */
    addExclamation( & msg)
    say(msg)

    /* 3. Variadic Function */
    says("Hello", "New", "World")

    /* 4. Function Return */
    total: = sum(1, 7, 3, 5, 9)
    println(total)

    count,
    total: = sums(1, 7, 3, 5, 9)
    println(count, total)

    /* 5. Anonymous Function */
    // 함수 전체를 변수에 할당하거나 다른 함수의 파라미터에 직접 정의된다.
    // '변수명(파라미터들)' 형태로 사용된다.
    // 일급 함수 -> 기본 타입과 동일하게 취급 -> 함수의 파라미터 전달 혹은 리턴값으로 사용된다.
    // type문을 사용한 함수 원형 정의

    multi: = func(i int, j int) int {
        return i * j
    }
    duple: = func(i string, j string) string {
        return i + j + i + j
    }

        r1: = calNum(multi, 10, 20)
    fmt.Println(r1)

    r2: = calStr(duple, "Hello", " Golang ")
    fmt.Println(r2)

    /* 6. Closure */
    next: = nextValue()

        println(next()) // 1
    println(next()) // 2
    println(next()) // 3

    anotherNext: = nextValue()
    println(anotherNext()) // 1 다시 시작
    println(anotherNext()) // 2

    /* 7. Go Collection - Array */
    var arr1[3] int
    arr1[0] = 1
    arr1[1] = 2
    arr1[2] = 3
    println(arr1[2])

    var arr2 = [3] int {
        1, 2, 3
    }
    var arr3 = [...] int {
        4, 5, 6
    }
    fmt.Println(arr2)
    fmt.Println(arr3[2])

    var a = [2][3] int {
        {
            1, 2, 3
        }, {
            4, 5, 6
        }, //끝에 콤마 추가
    }
    println(a[1][2])

    /* 7. Go Collection - Slice */
    // Go 배열은 크기를 동적으로 증가시키거나 부분 배열을 발췌하는 등의 기능이 없다.
    // Go Slice는 내부적으로 배열에 기초하여 만들어졌지만,
    // 이런 제약점들을 넘어 편리하고 유용한 기능을 제공한다.

    var s1[] int // 슬라이스 변수 선언 (크기를 지정하지 않는다)
    s1 = [] int {
        1, 2, 3
    }
    s1[1] = 10
    fmt.Println(s1)

    // make를 활용하여 슬라이스 생성
    s2: = make([] int, 5, 10) // Slice type, Length, Capacity
    println(len(s2), cap(s2))

    // 부분 슬라이스
    s3: = [] int {
        0, 1, 2, 3, 4, 5
    }
    s3 = s3[2: 5] // 2, 3, 4
    s3 = s3[1: ] // 3, 4
    fmt.Println(s3) // 3, 4 출력

    // 슬라이스 병합과 복사
    s4: = [] int {
        0, 1
    }

    // 하나 확장
        s4 = append(s4, 2) // 0, 1, 2
        // 복수 요소들 확장
    s4 = append(s4, 3, 4, 5) // 0,1,2,3,4,5

    fmt.Println(s4)

    /* 8. Go Collection - Map */
    tickers: = map[string] string {
        "GOOG": "Google Inc",
        "MSFT": "Microsoft",
        "FB": "Facebook",
    }

        println(tickers["GOOG"])

    // 추가 혹은 갱신
        tickers["NV"] = "NAVER"
    tickers["FB"] = "FaceBook"

    fmt.Println(tickers)

    noData: = tickers["KKO"] // 값이 없으면 nil 혹은 zero 리턴
    println(noData)

    // 삭제
    delete(tickers, "FB")
    fmt.Println(tickers)

    // map 키 체크
    val,
    exists: = tickers["MSFTS"]
    if !exists {
        println("No MSFT ticker")
    } else {
        fmt.Printf("Value is %s", val)
    }

    // for range 문을 사용하여 모든 맵 요소 출력
    // Map은 unordered 이므로 순서는 무작위
    for key,
    val: = range tickers {
        fmt.Println(key, val)
    }
}

// Pass By Value
func say(msg string) {
    println(msg)
}

// Pass By Reference
func addExclamation(msg * string) { * msg += "!"
}

// Variadic Function
func says(msg...string) { // 메소드 오버로딩이 지원되지 않는다?
    for _, s: = range msg {
        println(s)
    }
}

// Function Return
func sum(nums...int) int { // 파라미터 괄호 뒷 부분에 적어준다.
    s: = 0
    for _,
    n: = range nums {
        s += n
    }
    return s
}

// Named Return Parameter
func sums(nums...int)(count int, total int) { // 명시적으로 리턴될 파라미터를 적는다.
    for _, n: = range nums {
        total += n
    }
    count = len(nums)
    return // return만 적어준다.
}

// Closure
func nextValue() func() int {
    i: = 0
    return func() int {
        i++
        return i
    }
}

 

패키지, 구조체, 메서드, 인터페이스 (자바와 비교)

/* Package */
// 패키지를 통해 코드의 모듈화, 코드의 재사용 기능을 제공한다.
// 표준 라이브러리 패키지들은 GOROOT/pkg 안에 존재한다.
 
// Main 패키지
// - Go Compiler에 의해 특별하게 인식된다.
// - 해당 패키지를 공유 라이브러리가 아닌 실행 프로그램으로 만든다.
// - 그리고 이 main 패키지 안의 main() 함수가 프로그램의 시작점이 된다.
// - 공유 라이브러리로 만들 때에는, main 패키지나 main 함수를 사용하면 안된다.

// 패키지 Scope
// - 패키지 내에는 함수, 구조체, 인터페이스, 메서드 등이 존재하는데,
// - 이들의 이름(Identifier)이 첫문자를 대문자로 시작하면 이는 public으로 사용할 수 있다.

// 패키지 init 함수와 alias
// - init() -> 패키지 실행 시 처음으로 호출되는 함수
// - alias -> 단지 패키지 내부 init()만 실행하려 할 때 import _ "PATH"

/* Java */
interface Drawer {
    public void Draw();
}

class Circle implements Drawer {
    int r;
    Circle(int r) {
        this.r = r;
    }
    public void Draw() {
        System.out.println("Circle is Draw : " + r);
    }
}

class Rectangle implements Drawer {
    int w, h;
    Rectangle(int w, int h) {
        this.w = w;
        this.h = h;
    }
    public void Draw() {
        System.out.println("Rectangle is w=" + w + " h=" + h);
    }
}

public class MyMain {
    public static void DrawForm(Drawer d) {
        d.Draw();
    }
    public static void main(String[] args) {
        Circle myC = new Circle(5);
        DrawForm(myC);
        Rectangle myR = new Rectangle(4, 5);
        DrawForm(myR);
    }
}

/* Go */
type Drawer interface {
    Draw()
}

type Circle struct {
    r int
}

func(c Circle) Draw() {
    fmt.Println("Circle is Draw : ", c.r)
}

type Rectangle struct {
    w, h int
}

func(r Rectangle) Draw() {
    fmt.Println("Rectangle is w=", r.w, " h=", r.h)
}

func DrawForm(d Drawer) {
    d.Draw()
}

func main() {
    var myC Circle = Circle {
        5
    }
    var myR Rectangle = Rectangle {
        3, 4
    }
    DrawForm(myC)
    DrawForm(myR)
}

 

defer

func data(fileName string) string {
    f: = os.Open(fileName)
    defer f.Close()
    contents: = io.ReadAll(f)
    return contents
}
  • 파일 입출력 기능을 구현할 때 유용한 키워드

 

단위 테스트

package pattern

import (
    "testing"
)

type patternTest struct { 
    in , out string
}

var patternTests = [] patternTest {
    patternTest {"aaaaa", "a"},
    patternTest {"ababab", "ab"},
    patternTest {"abaaba", "aba"},
    patternTest {"c.c.c.", "c."},
    patternTest {"abcdefg", "abcdefg"},
}

func TestPatterns(t * testing.T) {
    for _, e: = range patternTests {
        v: = getPattern(e.in)
        if v != e.out {
            t.Errorf("getPattern(%s) = %s, but want %s", e.in, v, e.out)
        }
    }
}
profile
개발자로 일하는 김찬영입니다.

0개의 댓글