Пользовательские типы строк в Go

Как я могу создать собственный тип в Go, который ограничен определенным списком строковых значений? например

type Suit = "Spade" | "Diamond" | "Club" | "Heart"
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
0
5 684
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В Go нет алгебраических типов данных (ADT). То, что вам нужно, это тип «сумма» в ADT. Например, в Swift и Rust есть перечисления для их поддержки. Go не имеет дженериков (пока); Варианта нет, Тип результата тоже.

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

package main

import "fmt"

type Suit int

const (
    Spade Suit = iota + 1
    Diamond
    Club
    Heart
)

type Card struct {
    suit Suit
    no   int
}

func (c *Card) PrintSuit() {
    switch c.suit {
    case Spade:
        fmt.Println("Its a Spade")
    case Diamond:
        fmt.Println("Its a Diamond")
    case Club:
        fmt.Println("Its a Club")
    case Heart:
        fmt.Println("Its a Heart")
    default:
        fmt.Println("Unknown!")
    }
}

func main() {

    c := Card{suit: Diamond}

    c.PrintSuit()

}  

Вы можете принять внешнюю функцию в таких методах, как PrintSuit, если логика обработки является внешней.

Этот маршрут ничего не делает для предотвращения присвоения значению Suit нежелательного значения (например, suit = Suit(123)), но, возможно, это наиболее подходящее решение для такого случая использования.

Hymns For Disco 24.12.2020 07:32

Нежелательные значения обрабатываются в условиях переключения. Важно то, что костюм начинается с iota + 1, а не просто с йоты, так как я хочу избежать присвоения значения 0 любому типу костюма, потому что это случай по умолчанию, когда кто-то делает Card{}. Также вам нужно позаботиться о правильной инициализации в функции NewCard, которая создает правильную карту {}.

Abhijit-K 24.12.2020 07:46
This route doesn't do anything to prevent a Suit вы можете рассмотреть возможность использования неэкспортируемого типа только с экспортируемыми значениями.
user4466350 24.12.2020 11:45

Определите псевдоним типа для string, то есть Suit. Suit — это тип, базовым типом которого является строка.

Теперь создайте константы типа Suit. В следующей оде Spade, Diamond, Club, Heart относятся к типу Suit. Теперь функция, в которой вы хотите, чтобы параметр был ограничен некоторым вводом (что невозможно); но что вы можете сделать, чтобы ограничить его принятие только типа Suit и передать любую из созданных переменных const.

// Define new type alias for string
type Suit  string

const (
    Spade Suit   = "Spade"
    Diamond Suit = "Diamond"
    Club Suit    = "Club"
    Heart Suit   = "Heart"
)

// function f only accepts parameter of type "Suit" 
func f(s Suit)  {
    fmt.Println(s)
}

func main()  {
    // Call the function f with Spade
    f(Spade)
}

это не то, как вы создаете типы данных с ограниченными значениями, а также, как сказал @Abhijit_K, go не поддерживает это.

whitespace 24.12.2020 05:03

this (type Suit string) не является псевдонимом типа, псевдоним типа имеет определенный синтаксис с определенным поведением. Это обычное объявление типа golang.org/ref/spec#Type_declarations

user4466350 24.12.2020 11:44

@whitespace В ответе уже написано, что это на самом деле невозможно.

shmsr 24.12.2020 12:47

Суть в том, чтобы иметь поддержку редактора, и это просто позволяет мне вводить что угодно в функцию. Я бы не рекомендовал это.

Lan Vukušič 26.07.2022 16:52

Другие вопросы по теме