[go lang] ์ธํฐํ์ด์ค
์ธํฐํ์ด์ค ์ ์, ๊ตฌํ
์ธํฐํ์ด์ค๋ ๋ฉ์๋ ์๊ทธ๋์ฒ์ ์งํฉ์ผ๋ก, ์ด๋ค ํ์
์ด ํน์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์๋ ์ธํฐํ์ด์ค์ ๋ช
์๋ ๋ฉ์๋๋ฅผ ๋ชจ๋ ๊ตฌํํ๋ฉด ๋๋ค. ์๋๋ DBManager
๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๊ณ *MySQLDBManager
ํ์
์ด ์ด๋ฅผ ๊ตฌํํ๋ ์์ ์ด๋ค.
// ์ธํฐํ์ด์ค ์ ์
type DBManager interface {
Connect(ip string, user string, pw string) bool
Query(q string) Data
Commit() bool
Disconnect() bool
}
// Concrete Type ์ ์
type MySQLDBManager struct {
...
}
// MySQLDBManager์ DBManager ๊ตฌํ
func (m *MySQLDBManager) Connect(ip string, user string, pw string) bool {
...
}
func (m *MySQLDBManager) Query(q string) Data {
...
}
func (m *MySQLDBManager) Commit() bool {
...
}
func (m *MySQLDBManager) Disconnect() bool {
...
}
์ด๋ฅผ ์ด์ฉํด ๋ค์๊ณผ ๊ฐ์ ํด๋ผ์ด์ธํธ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
var m DBManager
// MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋งค๋์ ๊ตฌํ ์ด์ฉ
m = MySQLDBManager{}
m.connect(...)
...
// Oracle ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋งค๋์ ๊ตฌํ ์ด์ฉ
m = OracleDBManager{}
m.connect(...)
...
Type Assertions, Type Switch
๋น ์ธํฐํ์ด์ค(empty interface; interface{}
) ๋ณ์์ ๊ฒฝ์ฐ ๋ชจ๋ ํ์
์ ๊ฐ์ ๋ด์ ์ ์๋ค.(์๋ํ๋ฉด ๋ชจ๋ ํ์
์ ์ ์ด๋ 0๊ฐ ์ด์์ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฏ๋ก) Type Assertion(ํ์
๋จ์ธ)์ ํตํด ์ธํฐํ์ด์ค ๋ณ์์ ๋ด๊ธด ๊ฐ์ ํน์ ํ์
์ผ๋ก ๋ค๋ฃฐ ์ ์๋ค. ์๋ ์์ ์ฝ๋๋ s = i.(string)
๋๋ s, ok = i.(string)
๋ก ๊ฐ์ ๊ฐ์ ธ์ค๋๋ฐ, ์ฒซ ๋ฒ์งธ ๋ฌธ๋ฒ์ ๊ฒฝ์ฐ ๊ฐ์ ๋จ์ธํ ํ์
์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์๋ค๋ฉด ๋ฐํ์ ์๋ฌ๋ฅผ ๋ฐ์์ํจ๋ค. ๋ ๋ฒ์งธ ๋ฌธ๋ฒ์ ๊ฒฝ์ฐ ๋จ์ธํ ํ์
์ผ๋ก ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๋ค๋ฉด ๊ฐ๊ณผ true๋ฅผ, ๊ทธ๋ด ์ ์๋ค๋ฉด ๋จ์ธํ ํ์
์ zero-value์ false๋ฅผ ๋ฐํํ๋ค.
var i interface{}
i = "Hello world"
s = i.(string)
s, ok = i.(string) // "Hello world", true
f, ok = i.(float64) // 0.0, false
switch ๋ฌธ์์ ํ์ ๋จ์ธ ์ด์ฉ์ ๋ค์๊ณผ ๊ฐ๋ค.
switch v := i.(type) {
case int:
...
case string:
...
default:
...
}
์์ : Error ๊ตฌํ
type error interface {
Error() string
}
'๊ฐ๋จํ' ์ ๊ณฑ๊ทผ ํจ์์ ๋ฐํ์ ์๋ฌ ๋ฐํ์ ์ถ๊ฐํ์. Error
์ธํฐํ์ด์ค๋ ์์ ๊ฐ์ด ์ ์๋์๋ค.
type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string {
return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}
func Sqrt(x float64) (float64, error) {
if x < 0.0 {
return 0.0, ErrNegativeSqrt(x)
}
z := 1.0
for i := 0; i < 10; i++ {
z -= (z*z - x) / (2 * x)
}
return z, nil
}
์์ : rot13 ์ํธํ ๋ฐ์ดํธ ์คํธ๋ฆผ ๊ตฌํ
type Reader {
func Read(b []byte) (n int, err error)
}
Reader
์ธํฐํ์ด์ค๋ ์์ ๊ฐ์ด ์ ์๋์๋ค. ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด b []byte
์ ๊ธฐ๋กํ๊ณ ์ฝ์ ๋ฐ์ดํธ์ n
์ ๋ฐํํ๋ค. ๋ง์ฝ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค๋ฉด error
๋ฅผ ๋ฐํํ๊ณ , ์๋ฌ๊ฐ ์๋ค๋ฉด nil
์ ๋ฐํํ๋ค.
type Rot13Reader struct {
r io.Reader
}
func rot(b byte) byte {
switch {
case 'a' <= b && b <= 'z':
return (b - 'a' + 13) % 26 + 'a'
case 'A' <= b && b <= 'Z':
return (b - 'A' + 13) % 26 + 'A'
default:
return b
}
}
func (r Rot13Reader) Read(buffer []byte) (int, error) {
n, err := r.r.Read(buffer)
if err != nil {
return n, err
}
for i := range n {
buffer[i] = rot(buffer[i])
}
return n, nil
}