key
는 단어이고 value
는 정의라는 식으로 생각할 수 있다. 그러므로 우리만의 사전을 만드는 것이 맵을 배우는 가장 좋은 방법이지 않을까?dictionary_test.go
는map
이라는 키워드로 시작하고 두 개의 타입이 있어야한다. 첫번째 타입은 키 타입으로 []
안에 쓰여 있다. 두번째는 값 타입으로, []
바로 다음에 온다.go test
를 실행하면 컴파일러는 ./dictionary_test.go:8:9: undefined: Search
와 함께 실패할 것이다.dictionary.go
dictionary_test.go:12: got '' want 'this is just a test' given, 'test'
.map[key]
배열에서 값을 가져오는 것과 동일하다.assertStrings
헬퍼를 만듦으로써 구현이 보다 일반적이게 되도록 만들었다.Search
함수를 만듦으로써 위에서 작성한 사전의 사용성을 개선한다.dictionary_test.go
:Dictionary
타입을 도입했는데 아직 선언하지 않았다. 그리고 Dictionary
인스턴스의 Search
함수를 호출하였다.assertStrings
를 변경할 필요는 없다.dictionary.go
에서:Dictionary
타입을 생성했는데, map
을 감싸는 얇은 래퍼로 동작합니다. 새로 정의한 커스텀 타입과 함께, Search
함수를 생성할 수 있다.Search
함수는 단어가 사전에 존재하지 않는다고 알려줄 수 있다. 이 방법으로 사용자가 단어가 존재하지 않는건지 아니면 단지 정의가 없는건지 궁금해하지 않게 된다 (이런 사전은 유용하지 않아 보인다. 그렇지만 다른 사례에서 키가 될 시나리오이다).Error
타입을 활용하는 것이다.Error
는 .Error()
메소드를 통해 문자열로 변환될 수 있다. 이 문자열은 assertion에 넘겨주는 대상이다. 또한 if
조건문을 통해 assertStrings
를 보호함으로써 error
가 nil
일 때 .Error()
를 호출하지 않게끔 보장한다.dictionary_test.go:22: expected to get an error.
Search
함수의 매직 에러를 별개의 변수로 뽑아냄으로써 이 에러를 제거할 수 있다. 이것은 더 나은 테스트를 만들 수 있도록 한다.ErrNotFound
변수를 사용함으로써 에러 문자열이 나중에 바뀌더라도 테스트가 실패하지 않게했다.Search
함수를 활용하여 사전 검사를 보다 쉽게했다.dictionary.go
&myMap
)하지 않고서도 수정할 수 있다는 것이다.nil
값이 가능하다는 점이다. 읽기 작업을 수행할 때 nil
맵은 빈 맵과 동일하게 동작하지만 nil
맵에 쓰기 작업을 시도한다면 이는 런타임 패닉을 일으키는 원인이 된다. 맵에 관해서는 여기서 더 알아볼 수 있다.make
키워드를 사용할 수 있다:hash map
을 생성하고 dictionary
가 이를 가리키게 한다. 이것은 절대로 런타임 패닉을 발생하지 않도록 보장하는 방법이다.Add
함수는 괜찮아보인다. 단지, 추가하고자 하는 값이 이미 존재하는 경우를 고려하지 않았다.Add
함수는 이미 존재하는 값을 수정해서는 안 된다. 사전에 새 단어만 추가해야한다.Add
함수가 에러를 반환하도록 수정하였는데 이는 새 에러 값인 ErrWordExists
를 검증한다. 이전 테스트를 수정하여 nil
에러를 검사하도록 했고 assertError
함수도 마찬가지다.Add
함수에서 값을 반환하도록 하지 않게 만들었기 때문에 컴파일러는 실패할 것이다.dictionary.go
파일에서nil
에러를 반환한다.switch
구문을 사용해서 에러를 매칭해보겠다. 이런 식으로 switch
구문을 활용하면 추가적인 안전망을 제공하는데, Search
함수가 ErrNotFound
가 아닌 에러를 반환하는 경우가 이에 해당한다.error
인터페이스를 구현하는 우리만의 DictionaryErr
타입을 만드는데 필요하다. Dave Cheney의 훌륭한 글에서 자세한 내용을 읽을 수 있다.Update
하는 함수를 만들어보자.Update
함수는 Add
함수와 매우 밀접하게 관련이 있다.Add
함수에서의 문제를 고치면서 이런 경우에 무엇을 해야할지 본 적이 있다. 그러모르 Add
함수와 엄청 유사한 무언가를 구현해보자.Add
함수와 같은 문제가 있다. 만약 새로운 단어를 전달한다면, Update
는 사전에 이를 추가한다.Update
함수를 수정하여 error
값을 반환하게 하였다.nil
에러를 리턴하게 했다.Add
함수와 거의 동일해보인다. dictionery
를 업데이트할 때와 에러를 리턴할 때를 뺴면 말이다.ErrNotFound
를 재사용하고 새로운 에러 타입을 추가하지 않을 수도 있다. 그러나, 업데이트에 실패했을 때 정확한 에러를 받는 것이 종종 더 나을 때가 있다.You can redirect the user whenErrNotFound
is encountered, but display an error message whenErrWordDoesNotExist
is encountered.
Delete
하는 함수를 만들어보자.Dictionary
를 생성하고선 단어가 지워졌는지 확인한다.go test
를 실행하면 다음 메시지가 나온다:delete
라는 내장 함수가 있다. 이 함수는 두개의 인자를 받는다. 첫번째 인자는 맵이고 두번째 인자는 삭제할 키다.delete
함수는 아무 것도 반환하지 않으며, 우리의 Delete
함수도 같은 방식에 기초할 것이다. 존재하지 않는 값을 삭제하는 일은 아무런 영향이 없다. Update
와 Add
함수와는 달리 API를 에러를 포함해서 복잡하게 할 필요가 없다.