В Go, как создать "конструктор" для типа со строковым базовым типом?

пытается иметь тип Char что это string одного символа. то, что я не могу сделать, это создать "конструктор". Я знаю, что упускаю что-то совершенно очевидное.

объявить Char тип

  type Char string

можно использовать этот тип с заявлением

  var c1 Char("abc")
  var c2 Char = "abc"

это не так: c1 и c2 нужно быть "a", а не"abc"

то, что я действительно хочу, это "конструктор", чтобы ограничить Char одним характер

 func Char( s string ) Char {
   var ch string = s[0]
   return ch
 }

конечно, имея type Char и func Char не так

 type.go:8: Char redeclared in this block

есть ли способ, чтобы заставить type инициализация через конструктор? или я вообще задаю правильный вопрос?

позвольте мне сказать по-другому: если пользователь говорит var c Char = "abc" они будут иметь неверное значение для типа Char - есть ли способ, чтобы заставить пользователя func NewChar(string) Char as Charтолько допустимый конструктор?

4 ответов


это . Обратите внимание на неэкспортируется Char struct поле c.

package char

type Char struct {
    c rune
}

func New(c rune) *Char {
    return &Char{c}
}

func (c *Char) Char() rune {
    return c.c
}

func (c *Char) String() string {
    return string(c.c)
}

вот пример того, как использовать .

package main

import (
    "char"
    "fmt"
)

func main() {
    var c = char.New('z')
    var d = c.Char()
    hello := "Hello, world; or สวัสดีชาวโลก"
    h := []rune(hello)
    ก := char.New(h[len(h)-1])
    fmt.Println(c, "a-"+c.String(), '0' <= d && d <= '9', ก)
}

выход:

z a-z false ก

сначала см. Следующий пример.

package main

func main() {
    s := "hello 世界"
    //for getting characters from string

    cells := []int(s)
    for _, c := range cells {
        println(c, string(c))
        // You'll get
        // 104 h
        // 101 e
        // 108 l
        // 108 l
        // 111 o
        // 32  
        // 19990 世
        // 30028 界
    }

    bytes := []byte(s)
    for _, b := range bytes {
        println(b, string(b))
        // 104
        // 101
        // 108
        // 108
        // 111
        // 32
        // 228
        // 184
        // 150
        // 231
        // 149
        // 140
    }
}

значение []int (s) - "приведение к символам Юникода". Значение [] byte(s) - "приведение к байтам".

и, Go не имеет конструктора. В стиле Go пакет предоставляет функцию NewXXX () для объекта XXX.

type Client struct {
    // ...
}

func NewClient() *Client {
    return &Client{/* ... */}
}

обновление:

если Вы имеете в виду Char как "1 элемент строки", вы должны определить как следующее.

type Char int

или

type Char byte

ваш определение

type Char string

повторно определяет "строку". Затем он может хранить строку.


один символ юникода в Go представлен uint32 Вы можете сделать следующее:

type Char uint32
var a Char = 'a'

нет необходимости в конструкторе, так как вы можете просто использовать символьный литерал.


наряду с другими ответами, следует отметить, что Го не имеет такого понятия, как специальный синтаксис конструктора. Однако есть некоторые условности. Обычно, когда у вас есть пользовательский тип и вам нужен конструктор, вы пишете функцию NewT (), которая принимает любые необходимые параметры, выполняет инициализацию и возвращает один экземпляр указанного типа.

type Char string

func NewChar(s string) Char {
    if len(s) == 0 {
       return Char("")
    }
    return Char(s[:1])
}