변수 및 상수, 열거형

변수

  • 하나씩 선언
    • var {변수명} {변수 타입}
    • 초기화 하지 않으면 기본값으로 초기화 된다.
package main

import "fmt"

var d string //package level scope

func main() {
	var a bool
	var b int
	var c float32 //block level scope

	fmt.Println(a) //false
	fmt.Println(b) //0
	fmt.Println(c) //0
	fmt.Println(d) //
}
  • 여러개 한번에 선언
package main

import "fmt"

func main() {
	var (
		name string = "name"
		age  int32
	)

	age = 25
	fmt.Println(name) //name
	fmt.Println(age) //25
}
  • 짧은 선언
    • 반드시 제한된 범위의 함수 내에서 사용(전역으로는 사용 불가) => 코드 가독성을 높일 수 있다.
    • 선언 후 재할당 하면 예외 발생한다. 즉, 짧은 선언은 1회성으로 메소드 안에서만 사용하는 경우 명시적으로 알려주는 기능
package main

import "fmt"

func main() {
	age := 3 // 내부적으로 알아서 int 할당

	// age := 10 -> 에러 발생: "no new variables on left side of :="

	fmt.Println(age)
    
    //언제 사용하는지? 예시
    if i := 10; i < 11{ // i는 if문 밖에서는 사용 불가, if문이 끝나면 소멸된다.
    	fmt.Println("test")
    }
}

 

상수

  • const로 사용하며 선언과 동시에 초기화, 한번 선언 후에는 값 변경 금지
  • 함수 리턴값을 받을 수 없다.
// 위와 같이 한줄씩, 여러개 한꺼번에 선언하는 방식 모두 가능하다  
  const a, b int = 1, 2
  const c, d = "Hi", false
  const (
    x, y int = 16, 21
  )

 

열거형

연속된 성질의 상수를 나열할 때 사용한다. (자바의 enum class와 비슷...?), 일정한 규칙에 따라 나열된 수

iota를 적절히 활용해서 초기화 할 수 있다.

package main

import "fmt"

func main() {
	const (
		x = iota
		y
		z
	)

	fmt.Println(x, y, z)

	const (
		_ = iota
		a // 1
		_ // 생략하고 싶은 부분은 _로 스킵 가능하다.
		b // 3
		c // 4
	)

	fmt.Println(a, b, c)
}

 

제어문과 반복문

if문

  • 반드시 boolean만 검사 (자동 형 변환 불가)
  • 엄격한 form을 요구 - 줄맞춤이 중요하다, 괄호 생략하면 안됨
package main

import "fmt"

func main() {
    const a int = 4
    if a < 11{ // 여는 괄호가 아랫줄로 가면 오류남
    	fmt.Println("1")
    } else if a < 5 { // else if 또는 else는 닫는 괄호 바로 뒤에 위치해야 한다
    	fmt.Println("2")
    } else {
    	fmt.Println("3")
    }
}

 

switch문

  • if문에서 할 수 있는 모든 조건을 switch문에서 할 수 있다.
  • switch/case 뒤 expression 생략 가능
  • 기본적으로는 자동 break => fallthrough 넣으면 다음 case문을 실행한다. (마지막 케이스에는 fallthrough넣으면 오류)
  • type 분기 => 값이 아닌 타입으로 분기 가능
package main

import "fmt"

func main() {
	a := 7

	switch {
	case a > 0: // case 인덴트는 switch 위치와 동일해야
		fmt.Println("양수 ", a)
	case a == 0: // case문에 && || 연산자 모두 사용 가능
		fmt.Println("0 ", a)
	case a < 0:
		fmt.Println("음수 ", a)
	}
	

	switch b := 7; { // 범위가 정확히 switch문으로 제한된다 (scoped)
	case b > 0: // 위 case문과 동일하다. go에서는 이렇게 더 많이 씀
		fmt.Println("양수 ", b)
	case b == 0:
		fmt.Println("0 ", b)
	case b < 0:
		fmt.Println("음수 ", b)
	}
    
	switch i, j := 7, 8; { // 여러개도 가능
	case i < j:
		fmt.Println("i < j")
	case i == j:
		fmt.Println("i == j")
	case i > j:
		fmt.Println("i > j")
	}
    
	switch c := "GO"; c {
	case "GO": // c == "GO" 해줄 필요 없음
		fmt.Println("go")
	case "JAVA":
		fmt.Println("java")
	default:
		fmt.Println("불일치")
	}
    
	switch c := "GO"; c + "LANG" { // 이 영역에서 연산도 가능하다
	case "GOLANG", "GO": // 다양한 값 매칭 가능 
		fmt.Println("go")
	case "JAVA":
		fmt.Println("java")
	default:
		fmt.Println("불일치")
	}
}

 

for문

  • go에서는 while 없음, 반복문은 for만 제공된다
  • if와 마찬가지로 괄호 위치 중요하다
  • 자바처럼 루프에 label을 주고 continue, break에 사용할 수 있다
  • continue, break 다른 언어와 동일하게 사용할 수 있다
package main

import "fmt"

func main() {

	for i := 0; i < 5; i++ { // 괄호 여부 및 위치 중요, i++ 대신 i = i+1 이런식으로 해도 된다
		fmt.Println(i) // 0~4 출력
	}
    
	j := 0
	for j < 5; { // 위와 동일
		fmt.Println(j) // 0~4 출력
		j++ // 주의 후치연산은 go에서 리턴값이 없음 -> k := j++ -> 컴파일 에러
	}

	//무한루프 패턴
	sum, k := 0, 0
	for {
		if i > 100 {
			break
		}
		sum += i
		i++
		// ++i -> c.f. 전치 연산자는 go에서 정의하지 않음, 컴파일 에러난다.
	}
    
	//range용법
	location := []string{"Seoul", "Incheon", "Busan"}
	for index, name := range loc { //첫번째로 가져오는 것은 무조건 인덱스
		fmt.Println(index, name)
	}

	location := []string{"Seoul", "Incheon", "Busan"}
	for _, name := range loc { //인덱스 안가져오고 싶은 경우엔 이렇게 하면 된다
		fmt.Println(index, name)
	}
}

 

배열, 슬라이스, 맵

 

 

 

포인터는 허용하는데, 포인터 연산은 비허용

 

+ Recent posts