[generics] Go에 제네릭이없는 이유는 무엇입니까?

면책 조항 : 지금까지 바둑을 사용하는 것은 하루 밖에되지 않았으므로 많이 놓쳤을 가능성이 높습니다.

Go에서 generics / templates / whatsInAName에 대한 실제 지원이없는 이유를 아는 사람이 있습니까? 따라서 일반 map이지만 컴파일러에서 제공하는 반면 Go 프로그래머는 자신의 구현을 작성할 수 없습니다. Go를 가능한 한 직각으로 만드는 것에 대한 모든 이야기에서 왜 제네릭 유형을 사용할 수 있지만 새 유형을 만들 수 없습니까?

특히 함수형 프로그래밍과 관련하여 람다, 심지어 클로저도 있지만 제네릭이없는 정적 유형 시스템에서는 어떻게 작성 filter(predicate, list)합니까? interface{}좋습니다. 연결된 목록 등은 유형 안전성 을 희생 하여 수행 할 수 있습니다 .

SO / Google에 대한 빠른 검색은 통찰력을 나타내지 않았기 때문에 제네릭이 나중에 Go에 추가 될 것 같습니다. 나는 톰슨이 자바보다 더 잘할 것이라고 믿지만 왜 제네릭을 배제 하는가? 아니면 계획되어 있고 아직 구현되지 않았습니까?



답변

이 답변은 여기에서 찾을 수 있습니다 : http://golang.org/doc/faq#generics

Go에 일반 유형이없는 이유는 무엇입니까?

제네릭은 어느 시점에서 추가 될 수 있습니다. 일부 프로그래머는 이해하지만 우리는 그들에게 긴급함을 느끼지 않습니다.

제네릭은 편리하지만 유형 시스템과 런타임에서 복잡성이 발생합니다. 우리는 계속 생각하지만 복잡성에 비례하는 가치를 제공하는 디자인을 아직 찾지 못했습니다. 한편 Go에 내장 된 맵과 슬라이스, 빈 인터페이스를 사용하여 컨테이너를 구성하는 기능 (명시 적 언 박싱 포함)은 많은 경우 제네릭이 가능하게하는 코드를 작성하는 것이 가능하지 않다는 것을 의미합니다.

이것은 여전히 ​​미해결 문제입니다.


답변

이동 2

https://blog.golang.org/go2draft 에는 제네릭에 대한 초안 디자인이 있습니다 .

이동 1

러스 콕스의 이동 베테랑의 하나는 쓴 일반 딜레마를받을 블로그 게시물 그가 요구하는을,

… 느린 프로그래머, 느린 컴파일러 및 비대해진 바이너리 또는 느린 실행 시간을 원하십니까?

느린 프로그래머는 제네릭이없는 결과이고 느린 컴파일러는 제네릭과 같은 C ++로 인해 발생하며 느린 실행 시간은 Java가 사용하는 boxing-unboxing 접근 방식에서 비롯됩니다.

블로그에 언급되지 않은 네 번째 가능성은 C # 경로입니다. C ++와 같이 특수 코드를 생성하지만 필요할 때 런타임에 생성합니다. 정말 좋아하지만 Go는 C #과 매우 다르기 때문에 전혀 적용 할 수 없습니다.

나는의 기술처럼 인기있는 자바 1.4를 사용하여 언급해야 이동의 제네릭 프로그래밍 것과 캐스트 interface{}와 똑같은 문제를 겪고 복싱 – 언 박싱 컴파일시 타입 안전의 손실 외에, (즉, 우리가하고있는 일이기 때문에). 작은 유형 (예 : int)의 경우 Go는 interface{}유형을 최적화하여 interface {}로 캐스트 된 int 목록이 연속적인 메모리 영역을 차지하고 일반 int의 두 배만 차지하도록합니다. 그래도에서 캐스팅하는 동안 런타임 검사의 오버 헤드가 있습니다 interface{}. 참조 .

일반 지원을 추가하는 모든 프로젝트 (여러 개가 있고 모두 흥미 롭습니다)는 컴파일 타임 코드 생성의 C ++ 경로를 균일하게 사용합니다.


답변

제네릭이 현재 내장되어 있지는 않지만, 코드를 생성하는 작은 유틸리티와 함께 ​​주석을 사용하는 go 용 제네릭의 여러 외부 구현이 있습니다.

다음은 이러한 구현 중 하나입니다. http://clipperhouse.github.io/gen/


답변

사실에 따르면, 게시물 :

많은 사람들이 Go 팀의 입장이“Go will never have generics”라고 (잘못) 결론을 내 렸습니다. 반대로 우리는 Go를 훨씬 더 유연하고 강력하게 만들고 Go를 훨씬 더 복잡하게 만드는 잠재적 제네릭이 가지고 있다는 것을 이해합니다. 제네릭을 추가하려면 최대한 적은 복잡성으로 최대한의 유연성과 성능을 얻을 수있는 방식으로 수행해야합니다.


답변

Go 2에 대해 파라 메트릭 다형성 (제네릭)고려 중입니다 .

이 접근 방식은 형식 매개 변수에 대한 제약 조건을 표현하는 데 사용할 수 있는 계약 개념을 도입합니다 .

contract Addable(a T) {
  a + a // Could be += also
}

그런 다음 이러한 계약을 다음과 같이 사용할 수 있습니다.

func Sum(type T Addable)(l []T) (total T) {
  for _, e := range l {
    total += e
  }
  return total
}

이것은 이 단계에서 의 제안 입니다.


귀하의 filter(predicate, list)기능이 같은 유형의 매개 변수를 사용하여 구현 될 수있다 :

func Filter(type T)(f func(T) bool, l []T) (result []T) {
  for _, e := range l {
    if f(e) {
      result = append(result, e)
    }
  }
  return result
}

이 경우를 구속 할 필요가 없습니다 T.


답변