오늘은 Go에 있는 strcut 키워드를 사용해보겠습니다
구조체를 만드는데 C랑 크게 다르지 않습니다
package main
import "fmt"
type person struct {
name string
age int
food []string
}
func main() {
food := []string{"burger", "king"}
sleeg := person{"sleeg", 15, food}
sleeg = person{name: "sleeg", age: 18, food: food}
//sleeg := person{name: "nico", age: 18, food: food} 불가!
//이런식으로 코딩할 경우 person{name : "nico", 18, food}는 불가
name: ,age: ,food:
쓸 경우 변수명은 struct와 똑같아야 한다
fmt.Println(sleeg.name)
//fmt.Println(sleeg)
}
person이라는 타입의 구조체를 만듭니다
sleeg = person{name: 값, age: 값, food: 값} 이렇게 넣워봤는데 주석에도 있듯이 두 가지의 방식으로 구조체안에 값을 넣을 수 있습니다
하지만 name : 값, 18 이렇게 하나만 변수로 값을 넣어주는건 불가합니다 그리고 name은 struct랑 변수명이 같아야 합니다
이제 struct를 응용해서 다른 package에 있는 struct를 끌어와보겠습니다
이렇게 main.go 1개 account 폴더에 account.go 1개가 있습니다
먼저 account.go에서 struct를 만들어봅시다
// Account struct
type Account struct { //banckAccount면 접근 불가.. Private
owner string //owner여도 접근 불가 소문자는 안돼!
balance int
}
Account의 앞문자를 대문자로 하는 이유도 이제 다들 아실 거라고 생각합니다. 대문자가 와야 public 즉 다른 package에서도 쓸 수 있으니까요! 만약 Owner까지 대문자로 바꾸면 main.go에서는 Owner의 값도 임의로 변경할 수 있겠습니다 이렇게요
account := account.Account(Owner: "sleeg", Balance: 1000)
// 만약 Account안에 Onwer, Balance가 있다는 가정 대문자이니까 값 변경 가능
자 이제 좀 더 나가보겠습니다
//account.go 파일
package account
import (
"errors"
)
// Account struct
type Account struct { //banckAccount면 접근 불가.. Private
owner string //owner여도 접근 불가 소문자는 안돼!
balance int
}
var err_nomoney = errors.New("can`t withdraw") // error이름은 err~추천
// NewAccount creates Account
func NewAccount(owner string) *Account { //account의 복사본이 된다
account := Account{owner: owner, balance: 0}
return &account //account 즉 복사본의 주소를 return 합니다, 새로운 객체
}
// Deposit x amount on your account
func (a *Account) Deposit(amount int) { //a는 인자값 타입은 Account *Account는 호출한
//Account을 사용해라
a.balance += amount
}
// Balance of your account
func (a Account) Balance() int {
return a.balance
}
// Withdraw x amount from your account
func (a *Account) Withdraw(amount int) error {
if a.balance < amount {
return err_nomoney
//return errors.New("Cant`t withdraw you are poor")
}
a.balance -= amount
return nil // null or none을 뜻함
}
type Account 라는 구조체를 선언했었죠?
이제 NewAccount라는 Account의 주소를 반환하는 func을 만들었습니다
// NewAccount creates Account
func NewAccount(owner string) *Account { //account의 복사본이 된다
account := Account{owner: owner, balance: 0}
return &account //account 즉 복사본의 주소를 return 합니다, 새로운 객체
}
이제 NewAccount라는 메소드를 부른다면 Account 구조체 안에 owner값은 인자값 owner, balance는 0으로 만든 객체를 주소를 리턴하겠다! 라고 생각하면 되겠습니다
자 이제 우리는 함수를 사용해 볼겁니다 이렇게 말이죠
// Deposit x amount on your account
func (a *Account) Deposit(amount int) { //a는 인자값 타입은 Account *Account는 호출한
//Account을 사용해라
a.balance += amount
}
Go에서의 Pointer Receiver로 된 함수를 만들어봅시다
하나하나 뜯어보자면 Deposit을 부른 (main)에 있는 Account 구조체를 a라고 칭하겠다라는 뜻입니다 *이 붙기 때문이죠
(main에서 사용한 Account의 주소를 가져온다고 보면 편합니다)
그리고 지금 Deposit함수는 account package안에서 동작하기 때문에 balance가 public이 아니라도 접근이 가능합니다.
// Withdraw x amount from your account
func (a *Account) Withdraw(amount int) error {
if a.balance < amount {
return err_nomoney
//return errors.New("Cant`t withdraw you are poor")
}
a.balance -= amount
return nil // null or none을 뜻함
}
Withdraw라는 메소드인데 error형식을 반환합니다
err_nomoney는 따로 error코드를 설정한 변수입니다
이처럼 Go는 try, catch가 없기 때문에 이렇게 에러코드를 개발자가 직접 만들어줘야 합니다
error코드를 강제하죠 어떻게 보면 좋은 거 같습니다 내 마음대로 error코드를 짜면 좀 더 그 코드들을 깊이 이해할 수 있지 않을까요?
에러코드는 return error.New("~")이렇게 반환해도 되고 변수로 선언해줘도 됩니다.
아 여기서 nil은 null or none을 나타냅니다
이번에는 코드가 꽤 길어 github 주소를 남기도록 할게요
틀린점 & 질문은 댓글로 부탁드려요!
https://github.com/sleeg00/go/tree/main/Chapt_3_go
'Go' 카테고리의 다른 글
[Go] golang slice안에 특징 (0) | 2023.02.16 |
---|---|
[Go] Go루틴이란 무엇인가? (0) | 2023.02.16 |
[Go] append와 가비지 컬렉터의 관계 & if, switch문 알아보기 (0) | 2023.01.09 |
[Go] $GOPATH/go.mod exists but should not 오류 (0) | 2023.01.09 |
[Go] Go의 특별한 인자값 전달 (0) | 2023.01.08 |