ProgrammingLang/Go

[Go Lang] 2. 핵심 문법

jinkwon.kim 2020. 6. 9. 18:01
728x90
반응형

본 Go에 대한 모든 실습은 Linux(ubunutu)에서 진행 합니다. 

1. 선언과 관련 키워드 개념 및 사용법

  - 프로그램 개발 순서대로 나열

분류 키워드 설명 사용법
package package 현재 작업하는 파일 어느 package에 속하는지 선언 합니다.
- package 패키지명
package main
import 현재 작업하는 파일에서 사용 할 package를 선언 합니다
import (
  "패키지명"
  "패키지명"
)
import (
  "fmt"
  "log"
)
변수 var - 변수를 선언 합니다.
- go에는 초기화 안되는 변수가 없으며 초기화 값 아래 표기
    숫자 = 0, 
    boolean = false
    string = ""
    interface = nil
- 여러 방식의 선언이 가능 합니다.

1. var를 이용한 변수 선언
  - 초기화 표현식과 다른 명시적 타입이 필요하거나 값을
    나중
할당 돼 초기화 값이 중요하지 않은 경우에 사용
  - 타입이나 표현식은 둘 중 하나 생략 가능
    1) var 이름 타입 = 표현식
    2) var 이름, 이름, 이름 타입
    3) var 이름, 이름, 이름 = 표현식, 표현식, 표현식

2. 짧은 변수 선언
  - 함수안에서 지역 변수로 사용된다. 
    1) 이름 := 표현식

  - 짧은 변수 재 사용시 새로운  짧은 변수가 적어도 한개는 존재
    해야한다

    2) in, err :=  os.Open(infile)
       in, err :=  os.Createe(infile) // 컴파일 에러 
       out,err = os.Creawte(infile) // 에러 안남
3. new를 이용한 선언
  - 호출할때 마다 고유의 주소를 갖는 개별의 변수를 반환
    1) test := new(표현식)

[var를 이용한 변수 선언]
  - var test string = ""
  - var v1, v2, v3 int
  - var t1, f1, s1 = 1, 2.3, "test"

[짧은 변수 선언]
  - s := "test
const 변수를 상수화 합니다. 
  const 이름 타입 = 값
  const 이름 = 값
 
type 사용자가 정의한 이름으로 타입 선언을 합니다. 
  type 이름 내부-타입
type calcl int
함수 func 함수 정의시 사용합니다.  func f() {
}
구조체  struct 자료구조를 정의 합니다.
Go에서 struct는 필드 데이타만을 가지며, 메서드는 없습니다
// 정의 방법 
type person struct {
    name string
    age  int
}

// 사용법
  // 1. 객체 생성
    p := person{}

  // 2. 객체 생성 및 초기화 
var p1 person
p1 = person{"Bob", 20}
p2 := person{
           name: "Sean",
           age: 50
         }

 

 

2. 구문 관련 키워드 

  - 모든 사용시 ()가 없다고 생각 하면 외우기 편합니다.

분류 키워드 개념 사용법
조건문 - if, else
- switch, case, default
[if, else]
c/c++과 동일

[switch]
- switch 의 case가 상수 타입일 필요는 없다. 
- swtich 에서 break가 필요 없다.
[ if , else ]
  if k == 1 {
    fmt.Println("One")
  } else if k == 2 {  //같은 라인
    fmt.Println("Two")
  } else {   //같은 라인
    fmt.Println("Other")
  }

[ switch ]
1. 사용법 1 
switch os := runtime.GOS; os {\
  case "ok":
    fmt.Println("ok")
  case "fail":
    fmt.Println("ok")


}
2. 사용법 2 
switch time.Saturday {
  case today + 0:
    fmt.Println("Today.")
  case today + 1:
    fmt.Println("Tomorrow.")
  case today + 2:
    fmt.Println("In two days.")
  default:
    fmt.Println("Too far away.")
}
반복문 - for, continue, break
- range 
  (go에서 추가됨)
[for]
c/c++과 동일

[range]
range는 index와 value를 반환 합니다. 
c/c++과 동일

- range 사용법 
// for 다음 _ 의 의미는 빈 식별자를 의미하며 해당 값을 무시 하겠다는 의미
  nums := []int{1,2,3}
  sum :=0
  for _, num := range nums {
      sum += num
  }
  fmt.Println("Sum : ", sum)
//
분기문  goto c/c++과 동일 c/c++과 동일
반환 return c/c++과 동일 c/c++과 동일

 

2. 변수 scope 

  1) 변수의 scope

    - 컴파일러는 지역 변수를 heap이나 stack 중 어디에 할당 할지 결정 할 수 있지만 놀렙게도 이 선택은 변수 선언에

      var를 사용했는지 new를 사용했는지에 따라 결정 되지 않는다.

    - 지역 변수라도 package 수준의 변수로 접근이 가능 하다면 heap 에 할당이 된다. (검증 못함)

          

  2) 변수의 할당

    (1) 기본 할당 

      - 이름 = 값

        Ex) test = 1

    (2) tuple 할당

      - 이름1, 이름2 = 값, 값

      - 이름3, 이름4 = 이름1, 이름2

        Ex) test1 test2 = 1, 2

             test3, test4 = test1, test2

 

3. 타입 관련 키워드 

구분 상세 타임 키워드 개념 사용법
기본 타입 정수 int8, int16, int 32, int64
uint8, uint16, uint 32, uint64
   
rune rune - int32에 대한 동의어로 통상적으로 값이 unicode pointer 임을 나타 냅니다.  
byte byte - uint8과 동일 원시 데이터 일부임을 강조  
uintptr uintptr - 길이가 지정돼 있지 않지만 포인터 값의 모든 bit를 저장할 수 있는 보호 없는 정보 타입
- 저 수준 프로그램에서만 사용됩니다. 
 
부동 소수점 float32
float64
   
복소수  complex64
complex128
   
boolean true
false
   
문자열 string    
문자열 리터럴  "hello" 리터럴(literal)이란 소스 코드의 고정된 값을 대표하는 용어다.  
결합 타입 배열 var 이름 [배열개수]타입
var 이름 [...]타입 = {값, 값, 값}
var 이름 [...]타입{index: 값, index: 값}
- C의 배열과 동일 하다. 
- Go에 추가된 형태로는 [...]을 로 하용하면 값의 갯
  수로 배열을 만듭니다
- 배열의 크기고 타입의 일종이다. 그래서 크기가 다
  르면 다른 타입 입니다
- 배열의 원소가 비교 할 수 있는 타입이면 배열
  타입도 배결 할 수 있기 때문에 배열도 == 으로
  비교가 가능합니다.
 
struct type test struct {
  ID int
  Name string
  number string
}
개념은 c/c++과 동일하며 사용법도 동일
리터럴 초기화 
sa := test {
    ID : 1,
    Name : "test:",
    number : "1-1-1",
}
 
참조 타입 포인터 var 이름 *int c/c++과 사용법 동일
[차이점] 
구조체 포인터 등을 접근 할 때 -> 연산자가 존재 하지 않아. 모두 . 으로 접근 해야 합니다. 



slice var 이름[]type = []type{1,2,3}
이름 := []type{1, 2, 3}
[정의] 
- 슬라이스는 '슬라이스 내부 배열'이라고 알려진
  배열의 원소들 일부 또는 전부에 접근 할 수 있는
  경량 자료구이다.

[배열과의 차이점]
- append를 이용하여 크기를 늘리 수 있다.
- 배열과 유사하다. 그러나 슬라이스는 비교가 할 수
  가 없다.
- 모든 원소가 같은 타입인 가변 길이 시퀀스를 나타
  냅니다.

[고유 특성]
- 슬라이스의 타입의 제로 값은 nil 입니다. 
  그래서 슬라이스가 비었는지 확인 할려면
  len(s) == 0을 사용해서 확인이 필요 합니다
1. var를 이용한 변수 선언
var slice1 []string = []string{ "test1,test2" }

2. 짧은 변수 선언
slice1 := []string{ "test1", "test2" }
map map[Key 타임]Value 타입 [정의] 
- hash table의 참조 입니다.
- key는 == 으로 비교 할 수 있어야 합니다.
- Key와 value의 타입은 같을 필요 없습니다 

[생성 방법 1 - make 사용] 
- 내장함수 make를 사용하여 생성 합니다. 
Ex) q := make(make[string]int)
q["kim"] = 32
q["jin"] = 32

[생성 방법 2 - map 리터럴 사용] 
- 마지막에  , 입력 필수 없으면 에러 납니다.
Ex) ages := map[string]int {
    "kim" : 31, 
    "jin"  :34,
}

 
함수 func 이름(파라미터 목록) (리턴 목록) {
  본문 
}
- 리턴 목록 위치가 기존 c/c++과 다름
- 리턴 값은 여러개의 목록이 올 수도 있습니다.
- 리턴 목록이 없으면 생략 가능

Ex) 
func find(url string) (string, int) {
   return "www.naver.com", 1
}

 
채널      
interface 타입 interface   인터페이스는 타입의 값을 보면 해당 값에 대해 알수 있는 것이 없다. 단지 이 값이 무엇을 하는지, 더 정확하게는 이 값에 있는 메소드에서 어떤 동작을 제공하는지만 알 수 있다.  

 

5. Go만의 특징

분류 키워드  개념 사용법
메소드 형태 만이 존재
func (연결할 struct 선언) "함수이름"() {
    method 정의
}
Go에는 C++처럼 Class가 존재 하지 않습니다 그래서 method를 struct에 연결하는 방식으로 Class를 구현 합니다. package main
import ("fmt")

type test struct {
    name string
    number string
}

//m test를 통하여 test struct와 info() method를 연결 합니다. 
func (m test) info() string {
  return m.name + " " +
           m.number
}

func main() {
  a := test {
    name: "jin"
    number: "1-1-1"
  }

  // test의 info() 호출
  fmt.Println(a.Info())
}

  defer defer 구문은 함수를 빠져나간 뒤에 실행 된다.
package main
 
import "os"
 
func main() {
    f, err := os.Open("1.txt")
    if err != nil {
        panic(err)
    }
 
    // main 마지막에 파일 close 실행
    defer f.Close()
 
    // 파일 읽기
    bytes := make([]byte, 1024)
    f.Read(bytes)
    println(len(bytes))
}
  채널 go 루틴에서 통신을 위한 것
package main
 
func main() {
  // 정수형 채널을 생성한다
  ch := make(chan int)
 
  go func() {
    ch <- 123   //채널에 123을 보낸다
  }()
 
  var i int
  i = <- ch  // 채널로부터 123을 받는다
  println(i)
}
  interface 구조체(struct)가 필드들의 집합체라면, interface는 메서드들의 집합체이다. interface는 타입(type)이 구현해야 하는 메서드 원형(prototype)들을 정의한다. 하나의 사용자 정의 타입이 interface를 구현하기 위해서는 단순히 그 인터페이스가 갖는 모든 메서드들을 구현하면 된다.


void pointer 처럼 사용 됩니다.


 











728x90
반응형