C ++ Шаблоноподобное поведение в Go

Например, у меня есть две разные структуры 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

Решение

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)

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]