Golang slice, map, struct

2021. 11. 9. 18:53Programming/JAVA, C++, Go, Rust

    목차
반응형

slice

slice 선언

s := make([]int, 5, 10)
  • 현재 길이: 5
  • 내부적 길이(capacity) 10의 크기
s := make([]int, 0, 5)
  • 현재 길이: 0
  • 내부 길이: 5 (할당 길이)

slice 추가

nodes := make([]*ListNode, 0, 10)

chunk_nodes := make([]*ListNode, 0, 10)

var node *ListNode
node = new(ListNode)

chunk_nodes = append(chunk_nodes, node)

nodes = append(nodes, chunk_nodes...)
  • ListNode를 pointer로 선언하여 할당
  • node에 대한 list인 chunk_nodes를 선언
  • chunk_nodes에 node 추가
  • 이후 chunk_nodes라는 list를 nodes라는 list에 추가

sub slice

s := []int{0, 1, 2, 3, 4, 5}
s = s[2:5]  // 2, 3, 4
s = s[1:]   // 3, 4

append

append 시 cap을 초과하면 내부적으로는 capacity의 2배로 할당함

s := []int{0, 1}
s = append(s, 2)
s = append(s, 3, 4, 5)

a := []int{1, 2}
b := []int{3, 4}
c := append(a, b...)

copy

src := []int{0, 1}
dst := make([]int, len(src), cap(src)*2)
copy(dst, src)

fmt.Println(dst) // [0 1]

map

map 선언

var ids map[string]string

ids는 nil 값을 지님

make 초기화

ids := make(map[string]string)

literal 초기화

animals := map[string]string {
    "D": "dog",
    "C": "cat",
}

key 유/무 확인

key_to_find := "my_key"

val, exist = ids[key_to_find]

if exist {
   fmt.Println("value = ", val) 
}

map enumeration

for k, v := range ids {
    ...
}

key deletion

delete(ids, "D")

struct

type Node struct {
    left Node*
    right Node*
    val int
}

node := Node{}
node.left = nil
node.right = nil
node.val = 0

node2 := Node{nil, nil, 2}

var node3 Node
node2 = Node{nil, nil, 3}

new로 할당하기

node4 := new(Node)

node4.val = 4
  • new로 할당할 시 모든 field는 0으로 초기화 됨
  • 이후 *Node를 반환함

struct constructor

func makeNode() *Node {
    node := Node{}
    node.left = nil
    node.right = nil
    node.val = 0

    return ndoe
}

method

type Node struct {
    left Node*
    right Node*
    val int
}


// value reciever
func (node Node) init() bool {
    node.left = nuil
    node.right = nil
    node.val = 0

    return true
}

// pointer receiver
func (node *Node) inc() {
    node.val += 1
}

node := Node{}
res := node.init()    // node의 값이 변경되지 않는다.
fmt.Println(node)     // 값이 0으로 유지됨을 확인할 수 있다.

node2 := Node{nil, nil, 0}
node2.inc()
fmt.Println(node2)    // 1로 변경된 것을 확인할 수 있다.

pointer reciever로 정의해야 caller node의 값이 변경된다.

interface

type Animal interface {
    Bark() bool
}

type Dog struct {
    name string
    bark string
}

type Cat struct {
    name string
    bark string
}

func (dog Dog) Bark() bool {
    fmt.Println(dog.name + dog.bark)
    return true
}

func (cat Cat) Bark() bool {
    fmt.Println(cat.name + cat.bark)
    return true
}

var dog, cat Animal
dog = Dog{"dog1", "bow"}
cat = Cat{"cat1", "mew"}

fmt.Println(dog.Bark())
fmt.Println(cat.Bark())
  • dog, cat instance를 Animal이라는 interface type으로 선언한다.
  • 이후 Dog을 생성하여 이를 dog에 할당하고, Cat을 생성하여 이를 cat에 할당한다.
  • 상속을 명시적으로 지정하는 부분의 코드가 없이 위와 같이 구현할 수 있다. (이게 좋은 것인가? 아니라고 본다)
  • 명확하게 struct(class)내에 method가 선언되지 않기에 오직 file을 잘 구성해야만 명확한 관리가 가능하다. (마치 C에서의 함수 포인터로 구현할때 처럼 말이다) 이것 역시 좋다고 보긴 어려울 듯 하다.
반응형

'Programming > JAVA, C++, Go, Rust' 카테고리의 다른 글

go 언어로 web server 만들기 1 (고 언어 웹 서버)  (0) 2021.12.30
go generic (고 언어 제네릭)  (0) 2021.12.22
Go empty interface  (0) 2021.12.09
Golang 기본 문법  (0) 2021.11.09
Golang introduction  (0) 2021.11.09