사전 만들기
나의 소중한 댕댕이 포도🍇에 대한 사전(
이라고 쓰고 매뉴얼이라고 읽는다)을 만들어보고자 한다.
(호옥시나 오해할까봐 그러는데 이건 니꼴라스의 강의에 기초해서 만든 것이다.
폴더는 아래와 같이 짜면 된다.
---learngo
main.go
---mydict
mydict.go
자, 드가자
STEP1. 검색기능 넣기
간단하게 map에 대해 설명하자면, 이게 진짜 python에서 얘기하는 dictionary에 가깝다. {Key:Value}구조이고, 원하는 값을 넣고 key로 value로 찾을 수 있다.
우선 mydict.go
파일에 가서 아래와 같이 적어준다.
package mydict
import "errors"
// Dictionary type
type Sajeon map[string]string
// Errors
var errNotFound = errors.New("No such word")
// Search method
func (s Sajeon) Search(word string) (string, error) {
definition, exists := s[word]
if exists {
return definition, nil
}
return "", errNotFound
}
우선, type Sajeon map[string]string
이라는 코드를 보면, Sajeon이라는 별명의 map(자료구조 중 하나)를 만든 것이다. 구조는 key도 value도 문자열(string)이 들어간다.
그리고 Search
method를 보면, Sajeon
에서 word를 찾는다. 이 때, 유용하게 쓰이는게 map의 특성인데 map은 key값을 넣으면 value와 ok(있는지 없는지, 즉 true인지 false인지)를 반환해준다. 그래서 그걸 definition
과 exists
로 받아주고 if문을 통해 확인해준다.
이 때 주의할 점이 return값이 definition, nil
인데, 그 이유는 우리가 위에서 (string, error)
를 받겠다고 선언했기 때문이다.
그리고 또 else의 return값이 "", errNotFound
인데 그 이유는 문자열로 바꿔주기 위해서이다.
그 뒤, main.go
에 가서 아래와 같이 확인하는 코드를 짜본다.
package main
import (
"fmt"
"github.com/chaiwon/learngo/mydict"
)
func main() {
dictionary := mydict.Sajeon{"Hungry": "Carrot"}
meaning, err := dictionary.Search("Bored")
if err != nil {
fmt.Println(err)
}
fmt.Println(meaning)
}
dictionary := mydict.Sajeon{"Hungry": "Carrot"}
으로 사전에 넣어준다.
(포도는 배고프면 당근을 찾는다...🥕)
그 뒤, Search
method를 이용해 지루할 때("Bored")를 찾으면 당연히 안 나온다!
그런 단어 없답디다.
혹시 몰라 사전에 잘 들어갔는지 확인해보니,
당근을 주라고 잘 나옵디다 ✅
STEP2. 사전에 단어 추가하기
방금 만들었던 Search
method를 통해 넣고자 하는 단어가 있는지 확인하고 에러가 안 뜨면(즉, 이미 있는 단어라면) "이미 있음"을 반환하고, 에러가 뜨면(즉, 없는 단어라면(에러메세지 : "No such word")) 단어를 사전에 추가해주면 된다.
mydict.go
에 들어가서 아래와 같이 적어준다.
package mydict
import "errors"
// Dictionary type
type Sajeon map[string]string
// Errors
var errNotFound = errors.New("No such word")
var errAlready = errors.New("The Word already exists")
// Add method(using if)
func (s Sajeon) Add(word, definition string) error {
_, err := s.Search(word)
if err == errNotFound {
s[word] = definition
} else if err == nil {
return errAlready
}
return nil
}
// Add method(using case)
func (s Sajeon) Add(word, definition string) error {
_, err := s.Search(word)
switch err {
case errNotFound:
s[word] = definition
case nil:
return errAlready
}
return nil
}
여기서는 특별히 case문도 넣었는데, 찾아보니 case나 if나 역할적으로는 큰 차이가 없으나 걸리는 시간 차이란다. 보통 if문이 3개를 넘어가면 case를 쓰고 그 아래라면 if여도 상관없다고 한다.
코드가 간단하니 넘어가고
다음으로 main.go
에가서 method를 호출해보자.
package main
import (
"fmt"
"github.com/chaiwon/learngo/mydict"
)
func main() {
dictionary := mydict.Sajeon{"Hungry": "Carrot", "Bored": "Take a walk"}
fmt.Println(dictionary)
err1 := dictionary.Add("Bored", "Play")
if err1 != nil {
fmt.Println(err1)
}
err2 := dictionary.Add("Sleep", "Kick")
if err2 != nil {
fmt.Println(err2)
}
fmt.Println(dictionary)
}
위와 같이 method를 호출해서 확인해보자.
우선, dictionary에 "Hungry": "Carrot", "Bored": "Take a walk"
를 넣어준다.
(포도는 배고프면 당근, 심심하면 산책을 간다) ➡ 그 뒤, 이미 있는 "Bored"를 "Play"로 넣으려 해본다. ➡ 그리고 이번엔 아직 등록되지 않은 "Sleep"을 넣는다.(포도는 잘 때 나를 찬다🦶)
그 결과는 아래와 같다.
처음에 map에 잘 들어갔는지 확인하고, "Bored"를 넣으려 하자 The Word already exists
로 빠꾸 먹고, "Sleep"을 넣어주고 다시 map을 확인하니 잘 들어간 것을 확인할 수 있다.
STEP3. 사전 업데이트
이미 사전에 있는 단어지만, 업데이트를 하는 method를 추가해보자.
mydict.go
에 가서 아래와 같이 적어준다.
package mydict
import "errors"
// Dictionary type
type Sajeon map[string]string
// Errors
var (
errNotFound = errors.New("No such word")
errAlready = errors.New("The word already exists")
errCantUpdate = errors.New("Can't Update")
)
// Update method
func (s Sajeon) Update(word, newdef string) error {
_, err := s.Search(word)
if err == nil {
s[word] = newdef
} else if err == errNotFound {
return errCantUpdate
}
return nil
}
(error들은 묶어줘버리고)
순서는 똑같다. Search 해보고 err가 nil(즉, 에러가 없다 = 단어가 이미 있다)이면 newdef로 업데이트 해주고, 만약 err가 "단어 없음"이면 새로운 에러 메세지(errCantUpdate)를 반환한다.
다음은 main.go
에 가서 호출해보자.
package main
import (
"fmt"
"github.com/chaiwon/learngo/mydict"
)
func main() {
dictionary := mydict.Sajeon{"Hungry": "Carrot", "Bored": "Take a walk"}
fmt.Println(dictionary)
err1 := dictionary.Update("Bored", "Play")
if err1 != nil {
fmt.Println(err1)
}
fmt.Println(dictionary)
err2 := dictionary.Update("Sleep", "Kick")
if err2 != nil {
fmt.Println(err2)
}
fmt.Println(dictionary)
}
위와 같이 작성하면,
사전에 {"Hungry": "Carrot", "Bored": "Take a walk"}
넣어주고 ➡ "Bored", "Play"
로 Update한다 ➡ 만약 저렇게 했는데 에러가 있다(즉 not nil)이면 err1을 return하고, 아니면 사전을 print해라 ➡ 다음으로 사전에 없는 "Sleep", "Kick"
을 넣는데 ➡ 만약 에러가 있으면 err2를 return하고, 아니면 사전을 print해라
라는 순서로 실행된다.
그 결과는 아래와 같다.
첫 줄에는 사전 잘 print 되었고, 그 다음은 Bored
가 사전에 이미 있기 때문에 Update가 잘 된 것을 볼 수 있고, 없는 단어인 Sleep
을 넣으려 하자 Can't Update
가 나온 뒤 다시 사전이 print된 것을 볼 수 있다 ✅
STEP4. 삭제
마지막으로 삭제를 볼 건데, 삭제는 간단해서 error도 없고 뭐 없다. 그냥 한 줄만 써주면 된다.
mydict.go
에서 아래 코드만 추가해준다.
// Delete method
func (s Sajeon) Delete(word string) error {
delete(s, word)
return nil
}
간단하쥬?😉
바로 main.go
에 가서 확인해보자.
package main
import (
"fmt"
"github.com/chaiwon/learngo/mydict"
)
func main() {
dictionary := mydict.Sajeon{"Hungry": "Carrot", "Bored": "Take a walk"}
fmt.Println(dictionary)
dictionary.Delete("Hungry")
fmt.Println(dictionary)
}
결과까지
위와 같이 Hungry
가 삭제된 것을 볼 수 있다 ✅
마무리🙆
method를 좀 더 자유자재로 다뤄보는 실습이었다. 특히 map이 굉장히 독특하고 재밌어서 흥미로웠다. 다음에 해 볼 URL Check 프로그램은 쪼오오끔 어렵지만 잘 작성해보도록 하겠다.
이번 실습의 전체코드는 아래와 같다.
package mydict
import "errors"
// Dictionary type
type Sajeon map[string]string
// Errors
var (
errNotFound = errors.New("No such word")
errAlready = errors.New("The word already exists")
errCantUpdate = errors.New("Can't Update")
)
// Search method
func (s Sajeon) Search(word string) (string, error) {
definition, exists := s[word]
if exists {
return definition, nil
}
return "", errNotFound
}
// Add method(using if)
func (s Sajeon) Add(word, definition string) error {
_, err := s.Search(word)
if err == errNotFound {
s[word] = definition
} else if err == nil {
return errAlready
}
return nil
}
// Add method(using case)
func (s Sajeon) Add(word, definition string) error {
_, err := s.Search(word)
switch err {
case errNotFound:
s[word] = definition
case nil:
return errAlready
}
return nil
}
// Update method
func (s Sajeon) Update(word, newdef string) error {
_, err := s.Search(word)
if err == nil {
s[word] = newdef
} else if err == errNotFound {
return errCantUpdate
}
return nil
}
// Delete method
func (s Sajeon) Delete(word string) error {
delete(s, word)
return nil
}