오픈소스 컨트리뷰트가 하고싶다. 오픈소스 컨트리뷰트를 하게 된다면 그 분야에 대해서 어느정도 알 수준이 될거라 생각하기 때문에 오픈소스 컨트리뷰트로 나를 증명하고 싶었다.
불편한 함수의 발견
go언어를 사용하던중에 os.Getenv()를 발견했는데 python과 다르게 default값을 정할 수 없었다. 함수의 정의는 이러하다.
key값을 name으로 갖고있는 환경변수를 갖고있다. name이 비어있으면 empty값을 reuturn한다. name이 비어있는지 확인하고 싶으면 LookupEnv를 사용하면 된다.
python은 default값을 정할 수 있는데 go는 안되나?
func Getenv(key string) string {
testlog.Getenv(key)
v, _ := syscall.Getenv(key)
return v
}
Getenv함수는 내부적으로 syscall.Getenv를 부른다. syscall.Getenv는 두가지 값을 반환하는데 첫번째 값은 환경변수의 value를 불러오고, 두번째 값은 key값이 존재하는지 여부를 bool값으로 가져온다. 두번째 반환값은 _ 를 사용해서 사용하지 않는다.
그렇다면 LookupEnv는?
func LookupEnv(key string) (string, bool) {
testlog.Getenv(key)
return syscall.Getenv(key)
}
똑같이 syscall.Getenv()를 불러오고, bool값 또한 반환한다. 위 함수로 환경변수의 key값이 비어있는지 확인할 수 있다.
사용하려면 직접 if문을 써서 함수를 만들어줘야 한다.
value, is_exist := os.LookupEnv("key")
if !is_exist {
os.Setenv("key", "default_value")
} else {
os.Setenv("key", value)
}
기본적으로 위와같이 if문을 통해서 기본값을 할당해주는 함수를 만들어서 써줘야한다.
stackoverflow 에서도 LookupEnv를 쓰거나 if문을 통해서 분기처리를 해야한다고 한다.
이거 많이 쓰는 함수이고 default값이 있으면 편할텐데.. 안되나?
왜 default값을 지원 안하는지, 그리고 이 불편한게 아직까지도 남아있을까 했는데 go언어에는 python과 같이 함수 인자에 default값을 할당할 수 없다는 문제가 떠올랐다.
def hello(s="hello world"):
print(s)
hello() # "hello world"
파이썬은 기본적으로 default value가 있지만 go는 지원하지 않는다. 하지만 구글링을 해보니 방법은 있었다.
func foo(params ...int) {
fmt.Println(len(params))
}
func main() {
foo()
foo(1)
foo(1,2,3)
}
위와같이 ...int 를 파라미터로 받으면 된다. ...은 파이썬의 *args와 유사해서 파라미터로 입력된 타입의 데이터를 몇 개 받을지 확실하지 않을 때 사용하는 문법이다. 위 예시에서는 params를 ...int를 파라미터로 받았고 params는 int형 slice가 된다. 따라서 params의 값이 없어도 len(params) == 0 이 되어서 foo()와 같이 사용할 수 있다. 따라서 다음과 같이 함수를 수정해주면 되겠다 싶었다.
func Getenv(key string, value ...string) {
testlog.Getenv(key)
v, b := syscall.Getenv(key)
if !b {
if len(value) == 1 {
return value[0]
} else if len(value) > 1 {
return errors.New("too many arguments")
}
return v
}
return v
}
좀 엉성하긴 하지만 위와같이 수정해주면 지금 쓰고있는 Getenv()에도 영향 없이 default값을 할당할 수 있겠다 싶었다.
근데.. 아무리 생각해도 내가 처음 생각한게 아닐거 같다.
역시나 구글링을 해보니 이미 누가 이슈를 올린적이 있다.
누군가가 답변을 달았다.
개발자가 직접 코드를 더 쓰는게 best인거 같다고 한다. 방법은 당연히 알고 있었지만 개선하면 좋겠다 싶었던건데 하기싫으면 복붙하던가 에디터를 설정하거나 하라고 한다.. 😅 파이썬의 default를 경험한 나로서는 사용자가 더 많이 쓰니까 개선하는게 좋지않나 싶었다.
golang의 메인테이너(?)또한 프로그램마다 구분하기를 원하고, 원치않음이 다르기 때문에 개발자가 직접 코드를 작성하는게 더 합리적으로 보인다는 코멘트를 남겼다.
아직 모르겠다.
사실 이 부분이 go의 철학과 관련이 있는지는 모르겠다. 일단 함수에 default값을 정할 수 없는것에서 사용자가 코드를 몇줄 더 적는게 더 낫다고 생각한건지.. go를 좀 더 공부하게 되고 깨닫게 되면 다시 글을 수정하러 와야겠다.