Инициализировать структуру с глобальной областью действия, где тип зависит от логического значения - PullRequest
0 голосов
/ 26 мая 2018

Я недавно начал использовать Golang и наткнулся на проблему:

У меня есть две структуры, human и alien, обе из которых основаны на структуре creature.Я хочу инициализировать один из них, основываясь на значении логического значения isAlien внутри оператора if.

При использовании нотации human := human{} или эквивалента пришельцев внутри блоков if для инициализации, экземпляры вызываютсянедоступен извне оператора if.

С другой стороны, обычное решение объявления типа и имени переменной перед оператором if и инициализации переменной внутри оператора if нене работают, потому что есть два разных типа:

var h human //use human or alien here?
if isAlien {
  h = alien{} //Error: incompatible types
} else {
 h = human{}
}
//same when swapping human with alien at the declaration

Я знаю, что мог бы просто объявить оба типа перед оператором if, но это решение не кажется мне элегантным.

Есть ли какое-то очевидное решение, которое я здесь упускаю?

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Как вы заметили, проблема четко представлена ​​следующим утверждением:

var h human //use human or alien here?

Если вы планируете использовать эту переменную h там после создания объектов, тогда тип h должен бытьтот, который может принимать либо human, либо alien в качестве значения.

Способ сделать это в Go - использовать ìnterface, который могут выполнять как alien, так и human.

Таким образом, вы должны объявить интерфейс как:

type subject interface {
    // you should list all functions that you plan to use on "h" afterwards
    // both "human" and "alien" must implement those functions 
}

Тогда:

var h subject

Подойдет.

0 голосов
/ 26 мая 2018

Итак, я собираюсь выйти на конечность и сказать, что вы, вероятно, думаете об этом неправильно.

Первый вопрос, который возникает у меня при рассмотрении вашего примера: каков тип возврата этой функции?Другими словами, какую подпись вам нужно h?Если alien имеет встроенную структуру creature (которая выглядит как шаблон наследования, которому вы пытаетесь следовать), и вы возвращаете human из своей функции после объявления h как creature, что угоднокоторая потребляет вашу функцию, будет знать только, что она имеет дело с creature, поэтому нет смысла объявлять ее human или alien в первую очередь.

Я подозреваю , что то, что вы действительно хотите сделать, это отойти от конкретных конструкций здесь и вместо этого использовать интерфейсы.В этом мире у вас будет интерфейс creature, и оба human и alien будут удовлетворять интерфейсу creature.Вы не обязательно знаете, с каким из них вы работали в нисходящем направлении, но вы сможете надежно вызывать creature методы, и будет вызвана соответствующая реализация human или alien.

...