일반적인 객체지향 언어인 JAVA, C++등과 달리 class, inheritance 등을 지원하지 않는다. 하지만 sturct를 활용하여 객체를 구현하고, channel을 통해 객체 간 통신(상호 작용)하며 embedding을 통해 컴포지션이 가능하다는 점에서 충분히 객체지향적이라고 할 수 있다.
type Account struct {
number string
balance float64
interest float64
}
var kim *Account = new(Account)
kim.number = "245-901"
kim.balance = 10000000
kim.interest = 0.015
type Account struct {
number string
balance float64
interest float64
}
hong := &Account{number: "245-902", balance: 15000000, interest: 0.04}
type Account struct {
number string
balance float64
interest float64
}
lee := new(Account)
lee.number = "245-903"
lee.balance = 13000000
lee.interest = 0.025
// 익명 선언
car := struct{name, color string}{"520d", "black"}
// 익명 구조체 리스트
cars := []struct{name, color string}{{"520d","black"},{"530i", "red"}}}
for _, c := range cars {
fmt.Printf("(%s,%s) ----- (%#v)\n", c.name, c.color, c)
}
함수는 기본적으로 Value 호출
변수의 값이 복사 후 내부에 전달된다
맵, 슬라이스 등은 참조 값(주소)으로 전달한다.
객체의 복사본을 만들어 함수에 전달한다.
Value 리시버로 전달받은 값은 변경하여도 원래 값은 수정되지 않는다.
type shoppingBasket struct{ cnt, price int }
// 결제 함수
func (b shoppingBasket) purchase() int {
return b.cnt * b.price
}
// 원본 수정x (값 전달 형식)
func (b shoppingBasket) rePurchaseD(cnt, price int) {
b.cnt += cnt
b.price += price
}
객체의 주소를 함수에 전달한다
객체의 메모리 위치에 대해 참조(그 자체를 전달)하기 때문에 함수 안에서 수행된 변경 사항에 대해서 원래 객체가 변경된다.
// 원본 수정(참조 형식)
func (b *shoppingBasket) rePurchaseP(cnt, price int) {
b.cnt += cnt
b.price += price
}
구조체.함수명()
type Car struct {
name string
color string
price int64
tax int64
}
// 일반 메서드
func Price(c Car) int64 {
return c.price + c.tax
}
// 구조체 <-> 메서드 바인딩
func (c Car) Price() int64{
return c.price + c.tax
}
bmw := Car{name:"520d", price:500000000, color: "white", tax: 50000000}
benz := Car{name:"220d", price:600000000, color: "white", tax: 60000000}
fmt.Println("ex : ", bmw.Price())
fmt.Println("ex : ", benz.Price())
“encoding/json” 패키지에서 제공
구조체로 타입을 정의할 때 태그를 이용하면 프로퍼티명을 변경할 수 있다.
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
JSON 문자열([]byte 형)로 변환
func Marshal(v interface{}) ([]byte, error)
data, err := json.Marshal(value)
func main() {
data, _ := json.Marshal(true)
fmt.Println(data)
fmt.Println(string(data))
}
boolean Type인 true를 받아 [116 114 117 101]라는 바이트 슬라이스를 반환한다.
이를 string() 함수를 통해 문자열로 변경하면 true를 얻을 수 있다.
JSON 문자열을 받아 자료구조로 변환
func Unmarshal(data []byte, v interface{}) error
err := Person.Unmarshal(data, &value)
func main() {
var temp bool
json.Unmarshal([]byte("true"), &temp)
fmt.Printf("%t\n", temp) // %t는 Boolean
}
첫번째 인자값으로 바이트 슬라이스를 넘겨준다.
두번째 인자값으로 결과를 담게될 변수 포인터를 넘겨준다.
메모리에 임시 저장된 데이터를 반환하지 않고, 스트림(파일, 네트워크 소켓등 데이터 입출력 장치)에 직렬화된 데이터를 쓰는데 사용한다.
type Encoder struct
func NewEncoder(w io.Writer) *Encoder
func (enc *Encoder) Encode(v interface{}) error
json.NewEncoder로 인코더 생성
json.Encode 함수로 JSON으로 변환
- 첫번째 인자값으로 NewEncoder로 설정한 출력 값으로 User 값을 보내 인코딩된 JSON문자열을 출력시킨다.
func main() {
u := User{"FDongFDong", 30}
// os.Stdout : 표준 출력
enc := json.NewEncoder(os.Stdout)
enc.Encode(u)
}
인코딩과 반대로 JSON 문자열을 값으로 바꾸는 기능
type Decoder struct
func NewDecoder(r io.Reader) *Decoder
func (dec *Decoder) Decode(v interface{}) error
생성된 디코더는 표준 입력으로 연결된 스트림을 갖게된다.
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
var u User
dec := json.NewDecoder(os.Stdin)
dec.Decode(&u)
fmt.Printf("%+v\n", u)
}
표준 입력으로부터 데이터가 들어오면 Decode(&u) 메서드에 의해 User 데이터로 변경된다.