Что такое руна?

что это rune в Go?

я гуглил, но Голанг говорит только в одной строке:rune псевдоним int32.

но почему целые числа используются повсюду, как случаи замены?

ниже приведена функция swapcase. Что все <= и -?

а почему бы и нет switch есть какие-то аргументы?

&& означает и но что r <= 'z'?

func SwapRune(r rune) rune {
    switch {
    case 'a' <= r && r <= 'z':
        return r - 'a' + 'A'
    case 'A' <= r && r <= 'Z':
        return r - 'A' + 'a'
    default:
        return r
    }
}

большинство из них от http://play.golang.org/p/H6wjLZj6lW

func SwapCase(str string) string {
    return strings.Map(SwapRune, str)
}

я понимаю, что это отображение rune to string, так что он может вернуть местами строки. Но я не понимаю, как именно!--2--> или byte здесь работает.

7 ответов


Руна литералы-это просто целочисленное значение (как вы написали). Они "сопоставляются" с их кодовой точкой Unicode. Например, рунный литерал 'a' на самом деле число 97.

поэтому ваша программа в значительной степени эквивалентна:

package main

import "fmt"

func SwapRune(r rune) rune {
    switch {
    case 97 <= r && r <= 122:
        return r - 32
    case 65 <= r && r <= 90:
        return r + 32
    default:
        return r
    }
}

func main() {
    fmt.Println(SwapRune('a'))
}

это должно быть очевидно, если вы посмотрите на отображение Unicode, который идентичен ASCII в этом диапазоне. Кроме того, 32 фактически является смещением между прописными буквами и нижний регистр кода символа. Добавить 32 to 'A' вы получаете 'a' и наоборот.


С ходу Лэнг выпуске: http://golang.org/doc/go1#rune

руна-это тип. Он занимает 32bit и предназначен для представления Unicode кода. В качестве аналогии набор английских символов, закодированный в "ASCII", имеет 128 кодовых точек. Таким образом может поместиться в байте (8бит). Из этого (ошибочного) предположения C рассматривал символы как "байты"char и "строки" как "последовательность символов"char*.

но угадай, что. Есть много других символов, изобретенных людьми, кроме abcde..' атрибутика. И их так много, что нам нужно 32 бит для их кодирования.

в golang потом string - это последовательность bytes. Однако, поскольку несколько байтов могут представлять кодовую точку руны, строковое значение также может содержать руны. Таким образом, он может быть преобразован в []rune, или наоборот.

пакет unicode http://golang.org/pkg/unicode/ смогите дать вкус богатства вызова.


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

строка не обязательно последовательность рун. Это обертка над "ломтиком байтов", ломтик, являющийся оберткой над массивом Go. Какая разница?

A руна обязательно является 32-разрядным значением, то есть последовательность рун обязательно будет иметь некоторое количество бит x*32. Строки, будучи последовательностью байтов, вместо этого имеют длину x * 8 бит. Если бы все строки были на самом деле в Unicode, это различие не имело бы никакого влияния. Поскольку строки являются срезами байтов, Go может использовать ASCII или любую другую произвольную байтовую кодировку.

строковые литералы, однако, должны быть записаны в источник, закодированный в UTF-8.

источник информация: http://blog.golang.org/strings


Я старался держать свой язык простым, чтобы непрофессионал понимал rune.

руна-это символ. Вот и все.

это один персонаж. Это символ из любого алфавита из любого языка из любой точки мира.

получить строку, мы используем

double-quotes ""

или

back-ticks ``

строка отличается от руны. В рунах мы используем

single-quotes ''

теперь руна также является псевдонимом для int32...Что?

причиной руна-это псевдоним int32 потому что мы видим, что со схемами кодирования, такими как ниже enter image description here

каждый символ сопоставляется некоторое число, и это число, которое мы храним. Например, a карты 97 и когда мы храним это число, это просто число, и поэтому руна-это псевдоним для int32. но это не просто любое число. Это число с 32 ' нулями и те' или '4' байт. (Примечание: UTF-8-это 4-байтовая схема кодирования)

как руны относятся к строкам?

строка-это набор рун. В следующем коде:

    package main

    import (
        "fmt"
    )

    func main() {
        fmt.Println([]byte("Hello"))
    }

мы пытаемся преобразовать строку в поток байтов. Вывод:

[72 101 108 108 111]

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


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

однако, есть также вопрос, связанный с switch не имея никаких аргументов. Это просто потому, что в Golang, switch без выражения-это альтернативный способ выражения логики if/else. Например, написание этого:

t := time.Now()
switch {
case t.Hour() < 12:
    fmt.Println("It's before noon")
default:
    fmt.Println("It's after noon")
}

это то же самое, что написать это:

t := time.Now()
if t.Hour() < 12 {
    fmt.Println("It's before noon")
} else {
    fmt.Println("It's after noon")
}

вы можете подробнее здесь.


(появилось ощущение, что выше ответы все еще не указали различия и отношения между string и []rune очень ясно, поэтому я бы попытался добавить еще один ответ с примером.)

As @StrangeworkВместо ответа спросил:string и []rune отличаются.

различия string & []rune:

  • string value - это байтовый срез только для чтения. И строковый литерал кодируется в utf-8. Каждая буква в string на самом деле принимает 1 ~ 3 байт, в то время как каждый rune принимает 4 байт
  • на string, и len() и индекс основаны на байтах.
  • на []rune, и len() и индекс основаны на руне (или int32).

отношения string & []rune:

  • при конвертации из string to []rune, каждый символ utf-8 в этой строке становится rune.
  • аналогично, в обратном преобразовании, когда конвертировать из []rune to string, каждый rune становится символом utf-8 в string.

советы:

  • можно конвертировать между string и []rune, но все же они разные, как по типу , так и по общему размеру.

(я бы добавил пример, чтобы показать, что больше очевидно.)


код

string_rune_compare.go:

// string & rune compare,
package main

import "fmt"

// string & rune compare,
func stringAndRuneCompare() {
    // string,
    s := "hello你好"

    fmt.Printf("%s, type: %T, len: %d\n", s, s, len(s))
    fmt.Printf("s[%d]: %v, type: %T\n", 0, s[0], s[0])
    li := len(s) - 1 // last index,
    fmt.Printf("s[%d]: %v, type: %T\n\n", li, s[li], s[li])

    // []rune
    rs := []rune(s)
    fmt.Printf("%v, type: %T, len: %d\n", rs, rs, len(rs))
}

func main() {
    stringAndRuneCompare()
}

выполнить:

запустите string_rune_compare.go

выход:

hello你好, type: string, len: 11
s[0]: 104, type: uint8
s[10]: 189, type: uint8

[104 101 108 108 111 20320 22909], type: []int32, len: 7

объяснение:

  • строка hello你好 имеет длину 11, потому что первые 5 символов каждый принимает только 1 байт, в то время как последние 2 китайских символа каждый занимает 3 байта.

    • таким образом, total bytes = 5 * 1 + 2 * 3 = 11
    • с len() on строка основана на байтах, таким образом, первая строка напечатана len: 11
    • поскольку индекс на строке также основан на байтах, то следующие 2 строки печатают значения типа uint8 (поскольку byte является псевдонимом типа uint8, в go).
  • при преобразовании string to []rune, он нашел 7 символов utf8, таким образом, 7 руна.

    • с len() on []rune основан на руне, таким образом, последняя строка напечатана len: 7.
    • если вы используете []rune через индекс, он получит доступ к базе на руне.
      Поскольку каждая руна из символа utf8 в исходной строке, таким образом, вы также можете сказать оба len() и индекс операции на []rune основаны на символах utf8.

руна-это значение int32, и поэтому это тип Go, который используется для представления кодовой точки Unicode. Кодовая точка Юникода или кодовая позиция-это числовое значение, которое обычно используется для представления отдельных символов Юникода;