니꼬쌤과 함께하는 Go언어!!

 

전에는 Bank예제로 struct를 살펴보았다

https://jejehoon.tistory.com/22

 

struct in Golang (수정)

Struct 이번에는 니꼬쌤이 설명해주신 struct라는 개념이 잘 이해되지 않아서 인터넷을 활용해 직접 찾아보았다 내가 생각하는 struct(아니라면 태클 부탁드립니다) : Go는 전통적인 객체지향 언어라고 불리는 파..

jejehoon.tistory.com

이번엔 Dictionary(사전) 예제로 struct를 쓰지 않고 type만 쓰는 것을 살펴보자

왜 struct를 쓰지 않을까?내 생각엔 필요한 요소는 단어와 정의뿐이라 그런 것 같다(물론 형태나 예문이 들어갈 수 있지만 기본적인 사전을 나타내고자 한 것 같다) 필요한 요소가 더 많다면 struct를 쓰는 게 더 효율적이나 그렇지 않다면 굳이 struct를 쓸 필요가 없다  

Type

먼저 mydict라는 폴더와 go파일을 만들고 package mydict해준다

타입을 정하는 type문에 struct가 아닌 map을 활용해서 Dictionary타입을 만들자 map은 키와 밸류로 2가지 요소가 들어간다 Dictionary에 딱 맞는 타입이다 map에 들어가는 요소는 단어와 정의 이므로 둘 다 string형태이다

package mydict

type (d Dictionary) map[string]string

사전의 기능은 무엇이 있을까? 1. 단어를 찾는다 2. 단어의 정의를 확인한다  이렇게 사전의 기능을 잘 활용하기 위해서는 단어가 필요하다 그렇다면 3. 단어를 추가하는 기능! 또 단어나 정의가 잘못되었다면 4. 삭제하는 기능! 여러 가지 기능들이 필요하다 물론 우리는 스크롤을 내려서 수많은 단어 중하나하나 단어를 찾고 확인하고 추가 또는 삭제할 수 있지만 힘들다 그래서 필요한 것은 바로 Method! 

Method

method는 struct의 것과 같고 일반 type문에서도 사용할 수 있다 단 receiver의 경우 reference type인지 아닌지에 따라  포인터를 사용하는지 안 하는지 나뉜다! 예를 들자면 struct에서는 *(포인터)를 안 쓴 경우 원래의 것이 그대로 복사되어 나타난다 하지만 map처럼 reference type은 값의 복사를 전제로 깔고 있어서 포인터를 사용하면 안 된다 

네 가지의 Method를 모두 작성해보자

package mydict

import "errors"

// Dictionary type
type Dictionary map[string]string

var (
	errNotFound   = errors.New("Not Found")
	errWordExists = errors.New("Word Exists")
	errCantUpdate = errors.New("Cant Update Non-existing Word")
	errCantDelete = errors.New("Cant Delete Non-existing Word")
)

//Search for a word
func (d Dictionary) Search(word string) (string, error) {
	value, exists := d[word]	
	if exists {
		return value, nil
	}
	return "", errNotFound
}

// Add a word to the dictionary
func (d Dictionary) Add(word, def string) error {
	_, err := d.Search(word)
	switch err {
	case errNotFound:
		d[word] = def
	case nil:
		return errWordExists
	}
	return nil
}

// Update a word
func (d Dictionary) Update(word, def string) error {
	_, err := d.Search(word)
	switch err {
	case nil:
		d[word] = def
	case errNotFound:
		return errCantUpdate
	}
	return nil
}

// Delete a word
func (d Dictionary) Delete(word string) error {
	_, err := d.Search(word)
	switch err {
	case nil:
		delete(d, word)
	case errNotFound:
		return errCantDelete
	}
	return nil
}

error는 struct와 동일하게 체크해주는 용도로 사용한다 Go는 거의 강제적으로 error를 체크해야 한다고 한다

  https://blog.golang.org/maps 여기서 map의 활용법에 대해서 알 수 있다 exist와 delete 같은 경우는 이 쪽을 참고하면 형태를 잘 파악할 수 있다

Search, Add, Update, Delete를 작성했는데 모두 단어가 없을 때의 error를 나타내 주었고 map type이기 때문에 *(포인터)를 쓰지 않았다 

그러나 각각에 들어가는 인자는 각 기능마다 다르다

Search 같은 경우는 정의가 아닌 단어를 찾기 때문에 word만

Add는 추가할 때 정의도 같이 추가해야 하기 때문에 word def 둘 다

Update는 정의를 바꾸는 것이기 때문에 def만 필요할 것 같으나 word로 찾아야 하기 때문에 둘 다 

Delete는 단어를 삭제하면 되기 때문에 word만(정의도 같이하려면 def)

이렇게 인자가 어떤 것이 들어가야 될지 생각해보고 정의하면 된다

 

 완성하기까지 중간중간 체크를 하면서 만들어야 한다

package main

import (
	"fmt"

	"github.com/pavk/learngo/mydict"
)

func main() {
	dictionary := mydict.Dictionary{"first": "First word"} //첫 단어
	baseword := "hello"
	definition := "Greeting"
	err := dictionary.Add(baseword, definition) //둘째 단어 추가
	if err != nil {
		fmt.Println(err) //추가 가능한지 확인
	}
	hello, _ := dictionary.Search(baseword)
	fmt.Println(hello) // 추가 되었는지 확인
	definition = "Bowing" 
	err2 := dictionary.Update(baseword, definition)//둘째 단어 업데이트
	if err2 != nil {
		fmt.Println(err2)//업데이트 가능한지 확인
	}
	word, _ := dictionary.Search(baseword)
	fmt.Println(word)// 업데이트 되었는지 확인
	err3 := dictionary.Delete(word, definition)//둘째 단어 삭제
	if err3 != nil {
		fmt.Println(err3)//삭제 가능한지 확인
	}
	check, _ := dictionary.Search(word)
	fmt.Println(check)//삭제 되엇는지 확인
}

결과는!!

 

추가되었고 업데이트되었고 삭제되었다

'노마드코더스 아카데미 > Go언어로 웹스크래퍼 만들기' 카테고리의 다른 글

struct in Golang (수정)  (0) 2020.03.17
Go웹스크래핑[3]  (0) 2020.03.13
Go웹스크래핑[2]  (0) 2020.03.12
Go웹스크래핑[1]  (0) 2020.03.11
Go 웹스크래핑[0]  (0) 2020.03.11

+ Recent posts