Например, у меня есть две разные структуры Foo
а также Bar
struct Foo {...}
struct Bar {...}
и много функций и других типов, построенных на них.
C ++ вкус:
template<typename T>
struct Identified {
T model;
std::string id;
};
template<typename T>
Identified<T> GetIdentifiedModel(std::string id) {
Identified<T> result;
T.id = id;
T.model.set(getSomeData(id)); // Common method for T
return result;
}
Как реализовать эти примеры в Go?
Что касается распространенных методов, интерфейсы выполняют свою работу, но я не вижу, как извлечь определенный тип из интерфейса, чтобы объявить его, вернуть его или что-то еще, и я больше не могу обрабатывать код копирования / вставки 🙂
Спасибо !
Изменить @Amd: https://ideone.com/rqpsQb
#include <string>
#include <iostream>
struct Foo {
char c;
void set(std::string s) {c = s[0];}; // We don't really care here
};
struct Bar {
int n;
void set(std::string s) {n = s.size();}; // We don't really care here
};
template<typename T>
struct Identified {
T model;
std::string id;
};
template<typename T>
Identified<T> GetIdentifiedModel(std::string id) {
Identified<T> result;
result.id = id;
// Obviously shouldn't be ID but for the example
result.model.set(id); // Common method for T
return result;
}
void assert(bool b) {
if (b) std::cout << "OK" << std::endl;
else std::cout << "There is a problem !" << std::endl;
};
int main() {
auto fooWithID = GetIdentifiedModel<Foo>("foo id");
auto barWithID = GetIdentifiedModel<Bar>("bar");
assert (fooWithID.model.c == 'f');
assert (barWithID.model.n == 3);
return (0);
}
1- Вы можете использовать
fooWithID := GetIdentifiedModel("foo id", &Foo{})
как этот рабочий образец (примерьте Игровая площадка Go):
package main
import "fmt"
type Foo struct {
c byte
}
func (t *Foo) set(s string) { t.c = s[0] }
type Bar struct {
n int
}
func (t *Bar) set(s string) { t.n = len(s) }
type Identified struct {
model T
id string
}
func GetIdentifiedModel(id string, t T) *Identified {
result := &Identified{model: t}
result.id = id
result.model.set(id)
return result
}
func assert(b bool) {
if b {
fmt.Println("OK")
} else {
fmt.Println("There is a problem !")
}
}
func main() {
fooWithID := GetIdentifiedModel("foo id", &Foo{})
barWithID := GetIdentifiedModel("bar", &Bar{})
assert(fooWithID.model.(*Foo).c == 'f')
assert(barWithID.model.(*Bar).n == 3)
}
type T interface {
set(string)
}
выход:
OK
OK
2- Вы можете использовать (это приятно читать: Identified model Foo
):
fooWithID := GetIdentifiedModel("foo id", &Identified{model: &Foo{}})
как этот рабочий образец (примерьте Игровая площадка Go):
package main
import "fmt"
type Foo struct {
c byte
}
func (t *Foo) set(s string) { t.c = s[0] }
type Bar struct {
n int
}
func (t *Bar) set(s string) { t.n = len(s) }
type Identified struct {
model T
id string
}
func GetIdentifiedModel(id string, result *Identified) *Identified {
result.id = id
result.model.set(id)
return result
}
func assert(b bool) {
if b {
fmt.Println("OK")
} else {
fmt.Println("There is a problem !")
}
}
func main() {
fooWithID := GetIdentifiedModel("foo id", &Identified{model: &Foo{}})
barWithID := GetIdentifiedModel("bar", &Identified{model: &Bar{}})
assert(fooWithID.model.(*Foo).c == 'f')
assert(barWithID.model.(*Bar).n == 3)
}
type T interface {
set(string)
}
выход:
OK
OK
Смотрите также: Один метод для обработки всех типов структур, которые встраивают одну общую структуру (json marshalling)
Других решений пока нет …