Perimeter(width float64, height float64)
함수를 작성할 수 있다. 여기서 float64
는 123.45
같은 부동 소수점 수에 대한 것이다.f
는 float64
에 대한 것이고, .2
는 소수점 2자리 출력을 의미한다../shapes_test.go:6:9: undefined: Perimeter
shapes_test.go:10: got 0.00 want 40.00
가 출력된다.Area(width, height float64)
함수를 만들어 본다.RectangleArea
와 같이 기능을 좀 더 구체적으로 지정할 수 있다. 더 나은 해결책은 이 개념을 캡슐화하는 Rectangle
이라고 불리는 자기만의 type 을 정의하는 것이다.float64
대신 Rectangle
을 사용하도록 코드를 리팩터링한다.myStruct.field
구문을 사용하여 구조체 필드에 접근할 수 있다.Rectangle
을 전달하는 것이 의도에 더 명확하게 전달하지만 앞으로 배워가는 구조체를 사용하는 것이 더 많은 이점이 있다는것에 동의해주길 바란다.Area
함수를 작성하는 것이다../shapes_test.go:28:13: undefined: Circle
Circle
타입을 정의할 필요가 있다../shapes_test.go:29:14: cannot use circle (type Circle) as type Rectangle in argument to Area
./shapes.go:20:32: Area redeclared in this block
Area(Circle)
을 만들 수 있지만, 여기서는 너무 과한 느낌이다.t.Errorf
를 부를 때 t
(testing.T
)의 인스턴스에서 Errorf
메서드라고 한다.Area(rectangle)
과 같이 원하는 곳 어디서나 기능을 호출할 수 있는 경우에는 "things"에 대해서만 메서드를 호출할 수 있다.type Circle has no field or method Area
func (receiverName ReceiverType) MethodName(args)
의 구문이다.receiverName
변수를 통해 해당 데이터에 대한 참조를 얻는다. 다른 많은 프로그래밍 언어에서 이것은 암시적으로 수행되며 receiverName
을 통해 수신기에 접근한다.Area
함수가 통과하도록 만들기 위해 math
패키지에서 Pi
상수를 빌려온다. (import 잊지 않아야 한다.).Area()
메서드를 호출한 다음 결과를 확인하는 것이다.Rectangle
과 Circle
테스트를 통과할 수 있지만 도형이 아닌 것을 전달하려고 하면 컴파일하지 못하는 일종의 checkArea
기능으로 쓸 수 있기를 바란다.Shape
가 무엇인지 Go에 알려주기만 하면 된다.Rectangle
과 Circle
을 만들었던 것처럼 새로운 type
을 만들고 있지만 이번에는 struct
가 아닌 interface
이다.interface
는 대부분의 다른 프로그래밍 언어의 인터페이스와는 상당히 다르다. 보통은 My type Foo implements interface Bar
라는 코드를 작성해야 한다.Rectangle
은 Area
메서드를 호출하여 float64
를 반환하므로 Shape
인터페이스를 만족시킨다.Circle
은 Area
메서드를 호출하여 float64
를 반환하므로 Shape
인터페이스를 만족시킨다.string
에 해당하는 메서드가 없으므로 인터페이스를 만족하지 않는다.Rectangle
인지 Circle
인지 Triangle
의 도형인지에 대해 어떻게 신경 쓸 필요가 없는지 주목한다. 인터페이스를 선언함으로써 도우미는 구체적인 유형으로부터 분리 되고 단지 그 일을 하는데 필요한 방법을 갖게 된다.shape
와 want
라는 두 개의 필드가 있는 []struct
를 사용하여 구조체를 선언한다. 그런 다음 슬라이스를 케이스로 채운다.Area
를 구현한 후 테스트 케이스에 추가하는 것은 쉽다. 게다가, 만약 Area
에 있는 버그가 발견된다면, 버그를 고치기 전에 새로운 테스트 케이스를 추가하여 테스트하는 것이 매우 쉽다.{Triangle{12, 6}, 36.0},
를 추가하기만 하면 된다../shapes_test.go:25:4: undefined: Triangle
Area()
메서드에 Triangle이 없기 때문에 도형으로 사용할 수 없음을 알려주고 있으므로 빈 메서드을 추가하여 테스트한다.shapes_test.go:31: got 0.00 want 36.00
MyStruct{val1, val2}
구조의 인스턴스를 생성하는 구문만 표시되었지만 선택적으로 필드 이름을 지정할 수 있다.테스트는 더 명확하게 말해준다, as if it were an assertion of truth, 작업의 연속이 아니다
Triangle
을 실행하다가 실패한 테스트에서 shapes_test.go:31: got 0.00 want 36.00
를 출력했다.Triangle
과 관련 있다는 것은 Triangle
을 가지고 작업하고 있었기 때문에 알고 있다. 하지만 테이블에 있는 20개의 케이스 중 하나에서 버그가 시스템에서 발생한다면? 어떤 경우에 실패했는지 개발자가 어떻게 알 수 있을까? 이것은 개발자에게 좋은 경험이 아니다. 실제로 실패한 사례를 찾기 위해 수동으로 검토해야 한다.%#v got %g want %g
로 변경할 수 있습니다. %#v
형식 문자열은 필드 값이 있는 구조를 출력하여 개발자가 테스트 중인 속성을 한 눈에 볼 수 있도록 한다.want
필드를 hasArea
와 같이 좀 더 설명적인 것으로 바꿀 수 있다.t.Run
을 사용하고 테스트 케이스 이름을 지정하는 것이다.t.Run
으로 실행하면 케이스 이름을 출력하기 때문에 실패시 테스트 출력이 명확해진다.go test -run TestArea/Rectangle
를 사용하여 특정 테스트를 실행할 수 있다.