본문 바로가기
프로그래밍/Golang

[GOLANG] 공부 (2)

by 채연2 2020. 10. 29.


* reflection : 실행 시점(runtime)에 인터페이스나 구조체 등의 타입 정보를 얻어내거나 결정하는 기능
- reflect.TypeOf(변수명이나 구조체명) > Name(), Size(), Kind() / 구조체 : FieldByName(필드명), FieldByName(필드명).Get(태그명) 
- reflect.ValueOf(변수명이나 구조체명) > Type(), Kind(), Float() ...
- reflect.ValueOf(변수명이나 구조체명) > 포인터 : Elem(), Elem().Int() (값을 다시 얻어와 타입에 맞게 가져옴) // 인터페이스 : Int() (바로 가져옴)
* reflection을 사용하여 동적으로 함수 생성 방법 > 타입별로 함수 구현 방지
var hello func()  // 함수를 담을 변수 선언
fn := reflect.ValueOf(&hello).Elem()  // hello의 주소를 넘긴 뒤 Elem으로 값 정보를 가져옴
v := reflect.MakeFunc(fn.Type(), h)  // h의 함수 정보를 생성
fn.Set(v) 
// hello의 값 정보인 fn에 h의 함수 정보 v를 설정하여 함수를 연결

 

* 사용자 정의 패키지 생성
1. $GOPATH\src 밑에 패키지명으로 쓸 폴더 생성
2. 폴더에 여러 go파일 생성 > 단, go 파일의 패키지명은 폴더명과 같아야 함
3. go install 하여 라이브러리 생성 > $GOPATH\pkg\windows_amd64 밑에 저장됨
※ 패키지 키워드와 함수 정의 바로 위에 //주석 형태로 설명을 작성. 여러 줄도 가능!! > $GOPATH\src 디렉터리에서 godoc -http=:6060 명령을 실행 > 웹 브라우저 http://127.0.0.1:6060/pkg/패키지명 으로 접속하면 패키지 문서 확인 가능

 

* 출력 형식 지정자 종류
- %v  : 모든 값 사용 가능한 기본 지정자 (슬라이스, 맵, 포인터, 구조체, 인터페이스 ...) / %+v 처럼 +를 붙이면 구조체의 필드도 함께 표시됨 ( {a:1 b:2} )
- %#v : 타입과 값을 함께 표현 ( map[string]int{"Hello":1"} // []int{1, 2, 3} )
- %T  : 타입 표현
- %%  : % 문자 출력
- %t  : bool 표현
- %b  : 2진수 표현

 

* encoding/json 패키지에서 제공하는 JSON 함수
- func Marshal(v interface{}) ([]byte, error): Go언어 자료형을 JSON 텍스트 변환
- func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error): Go언어 자료형을 JSON 텍스트 변환 및 들여쓰기
- func Unmarshal(data []byte, v interface{}) error: JSON 텍스트를 Go 언어 자료형으로 변환
* JSON 데이터를 Go 언어 자료형으로 가져오기
doc := `
{
"name": "maria",
"age": 10
}
`

var data map[string]interface{}
json.Unmarshal([]byte(doc), &data)
fmt.Println(data["name"], data["age"])

* Go 언어 자료형을 JSON 형태로 변환하기
data := make(map[string]interface{})
data["name"] = "maria"
data["age"] = 10
doc, _ := json.Marshal(data) // doc, _ := json.MarshalIndent(data, JSON문서 첫 칸에 표시할 문자열, 들여쓰기할 문자-공백이나 탭)
fmt.Println(string(doc))
* JSON 문서 쓰고 읽어오기
data := make([]Article, 1)
doc, _ := json.Marshal(data)
err := ioutil.WriteFile("./abc.json", doc, os.FileMode(0644))
=====
b, err := ioutil.ReadFile("./abc.json")
var data []Abc
json.Unmarshal(b, &data)

* net 패키지에서 제공하는 TCP 함수
- func Listen(net, laddr string) (Listener, error) //프로토콜, IP 주소, 포트 번호를 설정하여 네트워크 연결을 대기합니다.
- func (l *TCPListener) Accept() (Conn, error) //클라이언트가 연결되면 TCP 연결(커넥션)을 리턴
- func (l *TCPListener) Close() error //TCP 연결 대기를 닫음
- func (c *TCPConn) Read(b []byte) (int, error) //받은 데이터를 읽음
- func (c *TCPConn) Write(b []byte) (int, error) //데이터를 보냄
- func (c *TCPConn) Close() error //TCP 연결을 닫음
* 사용방법

ln, err := net.Listen("tcp", ":8000")  // TCP 프로토콜에 8000 포트로 연결을 받음
if err != nil {
fmt.Println(err)
return
}
defer ln.Close()  // main 함수가 끝나기 직전에 연결 대기를 닫음

for { // 무한루프를 돌면서 클라이언트의 연결을 기다림
conn, err := ln.Accept()  // 클라이언트가 연결되면 TCP 연결(conn)을 리턴
if err != nil {
fmt.Println(err)
continue
}
defer conn.Close()  // main 함수가 끝나기 직전에 TCP 연결을 닫음

go requestHandler(conn)  // 패킷을 처리할 함수를 고루틴으로 실행
}

func requestHandler(c net.Conn) { // 클라이언트에게서 받은 패킷을 처리하고, 클라이언트로 패킷을 보내는 함수
data := make([]byte, 4096)  // 4096 크기의 바이트 슬라이스 생성

for {
n, err := c.Read(data)  // 클라이언트에서 받은 데이터를 가져옴
if err != nil {
fmt.Println(err)
return
}

fmt.Println(string(data[:n]))  // 데이터 출력

_, err = c.Write(data[:n])  // 클라이언트로 데이터를 보냄
if err != nil {
fmt.Println(err)
return
}
}
}

 

320x100

'프로그래밍 > Golang' 카테고리의 다른 글

[GOLANG] 공부 (4)  (0) 2020.10.29
[GOLANG] 공부 (3)  (0) 2020.10.29
[GOLANG] 공부 (1)  (0) 2020.10.29

댓글