#TIL GO 4회차

송정석·2022년 5월 16일
0
post-thumbnail

map

Key Type 으로 가능 한 것들은 아래와 같다
기본 자료형 , String, Pointer 형식 (결국 정수형), Struct, array
map, slice

참조 : https://go.dev/blog/maps


value Type은 아무거나 가능하다.

type Vertex struct {
	Lat, Long float64
}

var m = map[string]Vertex{
	"Bell Labs": {40.68433, -74.39967},
	"Google":    {37.42202, -122.08408},
}

func main() {
	fmt.Println(m)
}
=========================================================================

var m = map[string]Vertex{
	"Bell Labs": Vertex{40.68433, -74.39967},
	"Google":    Vertex{37.42202, -122.08408},
}

func main() {
	fmt.Println(m)
}

// map[Bell Labs:{40.68433 -74.39967} Google:{37.42202 -122.08408}]
type Any interface{}

type JsonObject map[string]Any

func main() {
	data, _ := json.MarshalIndent(JsonObject{
		"id":   1,
		"name": "sjs",
		"sub": JsonObject{
			"hello": "world",
		},
	}, "", "\t")

	fmt.Println(string(data))
}
// {
//        "id": 1,
//        "name": "sjs",
//        "sub": {
//                "hello": "world"
//        }
// }

Function values

func compute(fn func(float64, float64) float64) float64 {
	return fn(3, 4)
}

func main() {
	hypot := func(x, y float64) float64 {
		return math.Sqrt(x*x + y*y)
	}
	fmt.Println(hypot(5, 12))
	fmt.Println(compute(hypot))
	fmt.Println(compute(math.Pow))
}
// 13
// 5
// 81 ( 3*3*3*3 )

Function closures

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-2*i),
		)
	}
}
// 0 0
// 1 -2
// 3 -6
// 6 -12
// 10 -20
// 15 -30
// 21 -42
// 28 -56      
// 36 -72
// 45 -90

Methhod(receiver)

type Vertex struct {
	X, Y float64
}

func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
	v := Vertex{3, 4}
	fmt.Println(v.Abs())
}
// 5

type Vertex struct {
	X, Y float64
}

func Abs(v Vertex) float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func Scale(v *Vertex, f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

func main() {
	v := Vertex{3, 4}
	Scale(&v, 10)				// <= 포인터 값을 넘겨줘야함
	fmt.Println(Abs(v))
}
// 50
type Vertex struct {
	X, Y float64
}

func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

func ScaleFunc(v *Vertex, f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

func main() {
	v := Vertex{3, 4}
	v.Scale(2)
	ScaleFunc(&v, 10)

	p := &Vertex{4, 3}
	p.Scale(3)
	ScaleFunc(p, 8)

	fmt.Println(v, p)
}
type Vertex struct {
	X, Y float64
}

func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

func Scale(v *Vertex, f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

func main() {
	v := Vertex{3, 4}
	v.Scale(2)
	Scale(&v, 10)

	p := &Vertex{4, 3}
	p.Scale(3)
	Scale(p, 8)

	fmt.Println(v, p)

	Vertex{3, 4}.Scale(2) 			<== 컴파일 에러
	(&Vertex{3, 4}.Scale(2))
}

값 리시버를 사용 하는 이유 Readonly로 관리 가능
포인터 리시버를 사용 하는 이유 해당 인스턴스 값을 변경 가능 큰 구조체나 데이터의 값복사를 방지 할 수 있음




type I interface {
	M()
}

type T struct {
	S string
}

func (t *T) M() {
	if t == nil {
		fmt.Println("당신의 T nil로 대체 된건 아니고 nil 이다.")
		return
	}
	fmt.Println(t.S)
}

func main() {
	var i I // i.M() runtime error

	var t *T
	i = t
	describe(i)
	i.M()

	i = &T{"hello"}
	describe(i)
	i.M()
}

func describe(i I) {
	fmt.Println("(%v, %T)\n", i, i)
}
// (%v, %T)
//  <nil> <nil>
// 당신의 T nil로 대체 된건 아니고 nil 이다.
// (%v, %T)
// &{hello} &{hello}
// hello
type I interface {
	M()
}

func main() {
	var i I
	describe(i)
	i.M()
}

func describe(i I) {
	fmt.Println("(%v, %T)\n", i, i)
}

Type Assertion

func main() {

	var i interface{} = "HELLO"

	s := i.(string)
	fmt.Println(s)

	s, ok := i.(string)
	fmt.Println(s, ok)

	f, ok := i.(float64)
	fmt.Println(f, ok)

	f = i.(float64) //panic
	fmt.Println(f)
}
// HELLO
// HELLO true
// 0 false
// panic: interface conversion: interface {} is string, not float64

// goroutine 1 [running]:
// main.main()
//   /mnt/c/Users/sjs/Desktop/wecode/go/helloworld/main.go:20 +0x165
// exit status 2

Type Switch

func do(i interface{}) {
	switch v := i.(type) {
	case int:
		fmt.Printf("Twice %v is %v\n", v, v*2)
	case string:
		fmt.Printf("%q is %v bytes long\n", v, len(v))
	default:
		fmt.Printf("I don't know about type %T!\n", v)
	}
}

func main() {
	do(21)
	do("hello")
	do(true)
}
// Twice 21 is 42
// "hello" is 5 bytes long
// I don't know about type bool!
type Person struct {
	Name string
	Age  int
}

func (p Person) String() string {
	return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}

func main() {
	a := Person{"Arthur Dent", 42}
	z := Person{"Zaphod Beeblebrox", 9001}
	fmt.Println(a, z)
}
// Arthur Dent (42 years) Zaphod Beeblebrox (9001 years)

type Stringer interface {
    String() string
}  

Stringer 는 자신을 문자열로 설명할 수 있는 타입입니다. fmt 패키지 및 기타 여러 패키지는 값을 출력하기 위해 이 인터페이스를 사용합니다.

error

error 타입은 fmt.Stringer 와 유사한 내장 인터페이스 입니다

type error interface {
    Error() string
}

interface - Reader

io 패키지는 데이터 스트림의 읽기를 나타내는 io.Reader 인터페이스를 지정합니다.

type Reader interface {
	Read(p[]byte)(n int, err error)
}

image

type image interface {
	ColorModel() color.Model
	Bounds() Rectangle
	At(x int, y int) color.Color
}

profile
Foot print

0개의 댓글