본문 바로가기

Develop/DevOps

[Go] Golang을 공부하면서 알게된것들

반응형

참고자료

https://gobyexample.com/

 

Go by Example

 

gobyexample.com

변수 선언 방식 & 기초 (minor)

package main
import (
    "fmt"
)

func main() {
    var a int = 1
    
    var a string = "apple"
    // 두개 변수 선언 방식
    var a,b int = 1, 2
    
    // array 사용
    var a [5]int // [0,0,0,0,0]
    var b = [5]int{1,2,3,4,5}
    var c [5]int = [5]int{1,2,3,4,5}
    var d = [...]int{1,2,3,4,5} // 길이를 알지못할때?
    fmt.Println(d[2:]) // slice
    
    // map 사용 e.g. make(map[key-type]val-type)
    var m = make(map[string]int)
    m["k1"] = 7
    m["k2"] = 13
    fmt.Println(m) // map[k1:7 k2:13]
    
    // 특정 key를 이용해서 map에서 삭제
    delete(m, "k2")
    
    // map 전체 초기화
    clear(m)
    
    // 선언과 동시에 할당
    n := map[string]int{"foo": 1, "bar": 2}
    fmt.Println(n) // map[bar:2 foo:1]
    
    // range관련
    nums := []int{2,3,4}
    sum := 0
    for index, num := range nums {
        sum += num
    }
}

:=, =의 차이

:= 선언, 양도 및 재선언을위한 것이고, 변수의 유형도 자동으로 추론한다.

예를 들어, foo := 74과 밑의 나열들과 똑같은 의미이다. (참고로 함수내에서만 := 을 사용할 수 있다.)

// 1 
var foo int
foo = 74

// 2
var foo int = 74

// 3
var foo = 74

// 1,2,3은 이하의 코드로 대체할 수 있다.
foo := 74

:=으로 존재하는 변수를 재선언을 하는 경우 variables scope에 주의해야함. 즉, 아래와같이 사용할경우 맨 아래의 foo값은 선언타입의 초기값으로 되어있다.

func Test() {
  var foo int
  var x int = 1
  // if문의 scope
  if x < 3  {
    foo := 3 // foo에 재선언
    foo += 1
  }
  // if문 scope종료
  fmt.Println(foo) // foo 의 값은 0으로 출력됨
}

즉, 제대로 사용하려면 아래와같이 코드 수정이 필요함.

func Test() {
  var foo int
  var x int = 1
  // if문의 scope
  if x < 3  {
    foo = 3 // 수정 진행
    foo += 1
  }
  // if문 scope종료
  fmt.Println(foo) // foo 의 값은 4으로 출력됨
}

함수의 이름 PascalCase camelCase 차이

  • PascalCase → public함수가 되고 다른 패키지에서도 해당 함수 호출 가능
    • e.g. MyFunction
  • camelCase → private함수가 되고 다른 패키지에서는 해당 함수 호출이 안됨.
    • e.g. myFunction

함수 import

// something.go
package something

import "fmt"

func SayHello(){
	fmt.Println("SayHello Function")
}
// main.go
import (
	"fmt"
	"main/something" //함수 import
)

func main(){
	fmt.Println("hello")
	something.SayHello()
}

함수 가변 인자

한 함수에서 여러개의 인자값을 받을수있게 설정할수있음

func testFunction(str ...string) {
  fmt.Println(str)
}

func main() {
  testFunction("jae", "yung", "lee") // output: [jae yung lee]
  testFunction("jaeyunglee") // output: [jaeyunglee]
}

defer

defer예약어는 함수의 실행이 끝났을때 특정 동작을 예약할수있는 기능

func variableArgs(str ...string) {
	defer fmt.Println("is done!")
	fmt.Println(str)
}

func main() {
	variableArgs("hello", "world")
	// output
	// [hello world]
	// is done!
}

예외처리

package main
import (
    "fmt"
    "errors"
    "log"
)

func main() {
    var a, b int
    nm, err := fmt.Scanln(&a, &b)
    
    if err != nil { // 예외처리 부분
        panic(err) // 프로그램 종료
        //log.Panic(err) 이렇게 써도 종료가 되는듯
    }
}
  • errors패키지를 이용한 예외처리
func getResult(a int, b int) (int, error) {
    if a == 0 {
        return -1, errors.New("a should not be zero")
    }
    return a + b
}

같은 디렉토리(패키지) 다른 파일에 있는 함수 import하는방법

package에 대한 이름만 맞춰주면 바로 사용이 가능함

  • function.go
package main

func Add(a, b int) int {
    return a+b
}

func Sub(a, b int) int {
    return a-b
}
  • main.go
package main
import (
    "fmt"
)

func main() {
    a, b := 1, 2
    fmt.Println(Add(e,f)) // 3
    fmt.Println(Sub(e,f)) // -1
}

커스텀 모듈 import하는 방법

  • test라는 패키지 생성
# main.go 파일이 있는곳에서 test라는 새로운 package생성을 진행
mkdir test && cd test
go mod init test
touch test.go
  • test패키지에는 아래와같이 함수 생성
package test

import (
    "fmt"
)

func TestOutput(){
    fmt.Println("Hi, TestOutput Func")
}
  • 이후 main.go에 test패키지 포함되게끔 코드 작성
package main

import (
    "example/test" //example은 root 패키지
    "fmt"
)

func main() {
    test.TestOutput()
}
  • 바로 실행은 안되고, root디렉토리의 go.mod파일을 아래와같이 수정이 필요함
    • 수정완료 이후 go mod tidy명령어 수행필요
module example

go 1.22.6

require example/test v0.0.0 // 추가

replace example/test v0.0.0 => ./test // 추가

Const 타입 관련

const로 정의된 변수는 다른 언어와 동일하게 값을 변경할수없음.

또한, := 을 통해서도 선언이 될수없음

Golang에서는 array index를 마이너스로 줄수없다

python에서는 array가 존재하고 제일 마지막 인자값을 가져오고싶을때 아래와같이 코드를 작성함

a = [1,2,3,4]
print(a[-1]) # output 4

하지만 golang에서는 음수 인덱스를 제공하지않아서 아래와같이 작업해야함

  • 마이너스 값을 줄경우 다음과같은 에러 발생 → invalid argument: index -1 (constant of type int) must not be negative
var a = [5]int{1,2,3,4,5}
fmt.Println(a[len(a) - 1])
반응형