doUpdateWrong
은 값을 파라미터로 전달받고, (원본에 영향을 주지 않음)doUpdateRigth
은 주소를 파라미터로 전달받는다.package main
import (
"fmt"
)
type Adder struct {
start int
}
func (a Adder) AddTo(val int) int {
return a.start + val
}
func main() {
myAdder := Adder{
start: 10,
}
fmt.Println(myAdder)
fmt.Println(myAdder.AddTo(5))
fmt.Println(myAdder)
f1 := myAdder.AddTo // 메서드지만 함수이기도 하다. (method value)
fmt.Printf("%T\n", f1) // 그래서 타입이 func(int)로 나온다.
fmt.Println(f1(10)) // 또한, 함수이기 때문에 이렇게 사용할 수 있다.
f2 := Adder.AddTo // 위 f1은 myAdder라는 구조체 변수를 하나 생성한 후 그 변수의 AddTo함수를 사용한 것이지만, 이번엔 함수를 직접 가져온다.
fmt.Printf("%T\n", f2) // 그래서 타입이 func(int)로 나온다.
fmt.Println(f2(10)) // 또한, 함수이기 때문에 이렇게 사용할 수 있다.
}
package main
import (
"fmt"
)
type Adder struct {
start int
}
func (a Adder) AddTo(val int) int {
return a.start + val
}
func main() {
myAdder := Adder{
start: 10,
}
fmt.Println(myAdder)
fmt.Println(myAdder.AddTo(5))
fmt.Println(myAdder)
f1 := myAdder.AddTo // 메서드지만 함수이기도 하다. (method value)
fmt.Printf("%T\n", f1) // 그래서 타입이 func(int)로 나온다.
fmt.Println(f1(10)) // 또한, 함수이기 때문에 이렇게 사용할 수 있다.
f2 := Adder.AddTo // 위 f1은 myAdder라는 구조체 변수를 하나 생성한 후 그 변수의 AddTo함수를 사용한 것이지만, 이번엔 함수를 직접 가져온다.
fmt.Println(f2(myAdder, 10)) // Adder의 AddTo함수를 사용했지만, Adder구조체의 값이 필요하기 때문에 기존에 있던 Adder구조체 변수를 사용
fmt.Println(f2(Adder{start:20}, 10)) // 또는 이렇게 간단하게 구조체를 생성하여 사용할 수 있다.
}
city := []{'서울', '부산', '인천', '대전'}
mycity := '부산'
switch myCity{
//case city[0]: // 이런 방식으로 사용하면 인덱스별로 어떤 원소가 있는지 알고 있어야 한다.
case "서울" // 그러나 이렇게 사용할 수 있다.
"서울 출신이시네요"
if 서울 < 부산 // 이 비교연산도 가능하다. 인덱스 값으로 비교된다.
}
package main
import (
"fmt"
)
type MailCategory int
const ( // const블록은 상수 변수를 여러개 정의할 때 사용한다.
Uncategorised MailCategory = 10
Personal MailCategory = iota
Spam
Social
Advertisements
)
func main() {
//myMailTitle := "이것 한 번 드셔봐. 애들은 가라!"
// 로직 : 메일 타이츨을 보고 메일의 종류를 지정
myMailCat := Advertisements
fmt.Println(myMailCat)
switch myMailCat {
case Uncategorised :
fmt.Println("미분류 메일", Uncategorised )
case Spam:
fmt.Println("짭짤한 메일", Spam)
case Personal:
fmt.Println("개인적 메일", Personal)
case Advertisements:
fmt.Println("광고 메일", Advertisements)
}
}
package main
import (
"fmt"
)
type Employee struct {
Name string
ID string
}
func (e Employee) Description() string{
return fmt.Sprintf("%s (%s)", e.Name, e.ID)
}
type Manager struct { // 매니저도 직원중에 하나이기 때문에 Employee의 하위라고 할 수 있다. (개념상)
Employee // 보통 구조체니까, Emp Employee 이런식으로 사용하지만, '임베딩'으로 사용하기 위해 타입만 쓴다.
Reports []Employee
}
func main() {
m := Manager{ // Manager변수 m을 생성한다.
Employee: Employee{ // Manager에 임베딩된 Employee구조체의 초기화를 진행한다.
Name: "Bob Bobson",
ID: "12345",
},
Reports: []Employee{}, // Manager의 요소인 report를 정의한다.
}
fmt.Println(m.Employee.ID) // m 내부의 Employee 구조체의 ID를 출력, Employee의 ID
fmt.Println(m.ID) // 그러나 Employee가 임베딩되어 있기 때문에 그냥 m.ID로 사용해도 된다. 만약 따로 사용한다면, m.Employee.ID, m.ID 처럼 따로 사용할 수도 있다.
fmt.Println(m.Description())// Employee의 메소드또한 사용할 수 있다.
}
package main
import "fmt"
type Inner struct {
A int
}
func (i Inner) IntPrinter(val int) string { // Inner타입의 int형을 받아서 출력하고 문자열 반환하는 함수
return fmt.Sprintf("Inner: %d", val)
}
func (i Inner) Double() string { // Inner타입의 문자열을 받아서 두배한 후, IntPrinter에 보냄
result := i.A * 2
return i.IntPrinter(result)
}
type Outer struct { // Inner를 임베딩하고 문자열을 추가
Inner
S string
}
func (o Outer) IntPrinter(val int) string { // InterPrint의 Outer버전
return fmt.Sprintf("Outer: %d", val)
}
func main() { // Outer 정의
o := Outer{
Inner: Inner{ // 임베딩된 Inner정의
A: 10, // Outer의 문자열 추가
},
S: "Hello",
}
fmt.Println(o.Double()) // Double은 Outer의 메소드가 아니지만, Inner가 임베딩 되어있기 때문에 사용할 수 있다.
// 여기서 Outer의 IntPrinter가 아니라 Inner의 Printer가 나온다.
}
interface {
......
}
,(콤마) OK 관용구
를 사용할 수 있다.동기(Synchronous) VS 비동기(asynchronous)
<-
연산자를 사용하여 채널과 상호작용한다. package main
import (
"fmt"
)
func main() {
ch1 := make(chan int) //채널 1생성
ch2 := make(chan int) //채널 2 생성
go func() {
v := 1 // v에 1대입
ch1 <- v // 채널1에 v를 저장한다.
v2 := <-ch2 // v2에 채널2를 대입한다. // v2는 값이 아직 없다면 입력할떄까지 대기한다.
fmt.Println(v, v2) // v와 v2를 출력한다.
}()
v := 2 //v에 2 대입
ch2 <- v //채널2에 v넣기
v2 := <-ch1 // v2에 채널1 넣기 // 채널1에 값이 아직 없다면 입력할 떄까지 대기한다.
fmt.Println(v, v2) // v와 v2 출력
}
교착상태에 빠져서 exit status 2출력과 함께 에러가 출력되었다.
package main
import (
"fmt"
)
func main() {
ch1 := make(chan int) //채널 1생성
ch2 := make(chan int) //채널 2 생성
go func() {
v := 1 // v에 1대입
ch1 <- v // 채널1에 v를 저장한다.
v2 := <-ch2 // v2에 채널2를 대입한다. // v2는 값이 아직 없다면 입력할떄까지 대기한다.
fmt.Println(v, v2) // v와 v2를 출력한다.
}()
v := 2 //v에 2 대입
var v2 int
select{
case ch2 <- v: //채널2에 v넣기
case v2 = <-ch1: // v2에 채널1 넣기 // 채널1에 값이 아직 없다면 입력할 떄까지 대기한다.
}
fmt.Println(v, v2) // v와 v2 출력
}