एक रूण क्या है?


186

runeगो में क्या है ?

मैं गुगली कर रहा हूं लेकिन गोलंग केवल एक पंक्ति में कहता है: के runeलिए एक उपनाम हैint32

लेकिन कैसे आने वाले पूर्णांक का उपयोग स्वैपिंग मामलों की तरह किया जाता है?

निम्नलिखित एक समारोह स्वैपकेस है। सब क्या है <=और -?

और क्यों 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है stringताकि यह बदली हुई स्ट्रिंग को वापस कर सके। लेकिन मुझे समझ नहीं आता कि कैसे वास्तव में runeया byteयहाँ काम करता है।


सिडेनोट: यह वह नहीं करता है जो युवा पाठक यह चाहते हैं कि यह अंग्रेजी शब्द "कैफे" और अन्य के लिए करे - अकेले अन्य भाषाओं को दें। गो में इस तरह के परिवर्तन के वास्तव में उपयोगी वेरिएंट के लिए अच्छे समर्थन के साथ पुस्तकालय हैं।
RedGrittyBrick

2
मामले में कोई भी जानना चाहता है कि "रूण" शब्द कहां से आया है: en.wikipedia.org/wiki/Runic_(Unicode_block)
मैट ब्राउन ने

जवाबों:


146

रून शाब्दिक केवल 32-बिट पूर्णांक मान हैं ( हालांकि वे अप्रकाशित स्थिरांक हैं, इसलिए उनका प्रकार बदल सकता है )। वे यूनिकोड कोड पॉइंट का प्रतिनिधित्व करते हैं। उदाहरण के लिए, रनवे शाब्दिक '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'))
}

यह स्पष्ट होना चाहिए, यदि आप यूनिकोड मानचित्रण को देखें, जो उस सीमा में एएससीआईआई के समान है । इसके अलावा, 32 वास्तव में चरित्र के अपरकेस और लोअरकेस कोडपॉइंट के बीच ऑफसेट है। तो जोड़ने के 32लिए 'A', आप प्राप्त करते हैं 'a'और इसके विपरीत।


12
यह स्पष्ट रूप से केवल ASCII वर्णों के लिए काम करता है, न कि 'ä' जैसे संचित वर्णों के लिए, केवल 'ı' (U + 0131) जैसे अधिक जटिल मामलों को ही दें। गो के पास लोअर केस जैसे मैप करने के लिए विशेष कार्य हैं unicode.ToLower(r rune) rune
टॉपस्किप

2
और SwapCase फ़ंक्शन के साथ @ topskip के सही उत्तर को जोड़ने के लिए जो सभी कोडपॉइंट्स के लिए काम करता है और न केवल az:func SwapRune(r rune) rune { if unicode.IsUpper(r) { r = unicode.ToLower(r) } else { r = unicode.ToUpper(r) }; return r }
ANisus

22
रून्स int32 मान हैं। यही पूरा जवाब है। वे "मैप" नहीं कर रहे हैं ।
thwd

@ एलाइक्सएक्सेल: सिंपलफोल्ड का व्यवहार अनिवार्य रूप से एक ही है (यह सबसे अधिक रन के लिए टॉवलर और टौपर का भी उपयोग करता है)। कुछ मामले हैं जहां यह भिन्न होता है जैसे: >-> Dz, >-> dz, dz-> it। इसके बजाय मेरा SwapRune जाएगा: DZ-> would, >-> dz, dz-> DZ। मुझे आपका सुझाव बेहतर लगा :)
ANisus

3
तो रन सी चरस के समान हैं?
केनी वर्डेन

52

गो लैंग रिलीज़ नोट्स से: http://golang.org/doc/go1#rune

रूण एक प्रकार है। यह 32 बिट पर कब्जा कर लेता है और यह यूनिकोड कोडप्वाइंट का प्रतिनिधित्व करने के लिए है । सादृश्य के रूप में 'ASCII' में एन्कोड किए गए अंग्रेजी वर्णों में 128 कोड अंक होते हैं। इस प्रकार एक बाइट (8 बिट) के अंदर फिट करने में सक्षम है। इस (गलत) धारणा से C ने वर्णों को 'बाइट्स' char, और 'स्ट्रिंग्स' को 'वर्णों के अनुक्रम' के रूप में माना char*

लेकिन अंदाज़ा लगाओ कि क्या है। मनुष्यों द्वारा de एब्सडे .. ’प्रतीकों के अलावा कई अन्य प्रतीकों का आविष्कार किया गया है। और इतने सारे हैं कि हमें उन्हें एनकोड करने के लिए 32 बिट की आवश्यकता है।

गोलंग में तो stringएक अनुक्रम है bytes। हालाँकि, चूंकि कई बाइट्स एक रन कोड-पॉइंट का प्रतिनिधित्व कर सकते हैं, एक स्ट्रिंग मान में भी रेंस हो सकते हैं। तो, यह एक []rune, या इसके विपरीत में परिवर्तित किया जा सकता है ।

यूनिकोड पैकेज http://golang.org/pkg/unicode/ चुनौती की समृद्धि का स्वाद दे सकता है।


6
हाल ही में यूनिकोड 6.3 के साथ, 110,000 से अधिक प्रतीकों को परिभाषित किया गया है। इसके लिए प्रत्येक कोड बिंदु के कम से कम 21-बिट प्रतिनिधित्व की आवश्यकता होती है, इसलिए एक बिट की runeतरह है int32और इसमें बहुत सारे बिट्स हैं।
रिक -777

2
आप कहते हैं कि "ए stringए सी का अनुक्रम है rune" - मुझे नहीं लगता कि यह सच है? जाओ ब्लॉग : "एक स्ट्रिंग बाइट्स का एक गुच्छा है"; लैंग स्पेक जाओ : "एक स्ट्रिंग मूल्य बाइट्स का एक (संभवतः खाली) अनुक्रम है"
क्रिस मार्टिन

1
मैं अभी भी भ्रमित हूं, इसलिए स्ट्रिंग की एक सरणी या बाइट्स की एक सरणी है? क्या वे विनिमेय हैं?
गोगोफैन

1
@prvn यह गलत है। यह कहने जैसा है कि छवि बाइट्स का अनुक्रम नहीं है, यह पिक्सेल का एक अनुक्रम है। लेकिन, वास्तव में, नीचे, यह बाइट्स की एक श्रृंखला है। एक स्ट्रिंग बाइट्स की एक श्रृंखला है, न कि रन। कृपया युक्ति पढ़ें ।
इनक गमस

1
@prvn लेकिन, आप नहीं कह सकते not bytes। तो, आप कह सकते हैं: "स्ट्रिंग्स रन से बने होते हैं और बाइट से बने रन" कुछ इस तरह से। तो फिर। यह पूरी तरह सच नहीं है।
इनक गमस

28

मैंने अपनी भाषा को सरल रखने की कोशिश की है ताकि एक आम आदमी समझ सके rune

एक रनर एक चरित्र है। बस।

यह एक एकल पात्र है। यह दुनिया में कहीं से भी किसी भी भाषा से किसी भी वर्णमाला का एक चरित्र है।

एक स्ट्रिंग प्राप्त करने के लिए हम उपयोग करते हैं

double-quotes ""

या

back-ticks ``

एक स्ट्रिंग एक रूण से अलग है। रन में हम उपयोग करते हैं

single-quotes ''

अब एक भगोड़ा भी एक उपनाम है int32... उह क्या?

कारण रन के लिए एक उपनाम int32है क्योंकि हम देखते हैं कि नीचे कोडिंग योजनाओं के साथ यहां छवि विवरण दर्ज करें

प्रत्येक वर्ण कुछ संख्या में मैप करता है और इसलिए यह वह संख्या है जिसे हम संग्रहीत कर रहे हैं। उदाहरण के लिए, एक करने के लिए नक्शे 97 और जब हम उस नंबर की दुकान यह सिर्फ संख्या है और इतने के रास्ते रूण int32 के लिए एक उपनाम है। लेकिन सिर्फ कोई संख्या नहीं है। यह 32 'शून्य और लोगों' या '4' बाइट्स के साथ एक संख्या है। (नोट: UTF-8 एक 4-बाइट एन्कोडिंग योजना है)

कैसे तार तार से संबंधित है?

एक स्ट्रिंग रन का एक संग्रह है। निम्नलिखित कोड में:

    package main

    import (
        "fmt"
    )

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

हम एक स्ट्रिंग को बाइट्स की एक धारा में बदलने की कोशिश करते हैं। आउटपुट है:

[72 101 108 108 111]

हम देख सकते हैं कि प्रत्येक बाइट जो उस स्ट्रिंग को बनाती है वह एक रनर है।


2
A string is not a collection of runesयह सख्ती से बोलना सही नहीं है। इसके बजाय, स्ट्रिंग एक बाइट स्लाइस है, जिसे utf8 के साथ एन्कोड किया गया है। स्ट्रिंग में प्रत्येक चार वास्तव में 1 ~ 3 बाइट्स लेता है, जबकि प्रत्येक रन 4 बाइट्स लेता है। आप स्ट्रिंग और [] रन के बीच परिवर्तित कर सकते हैं, लेकिन वे अलग हैं।
एरिक वांग

2
रूण एक चरित्र नहीं है, एक रूनिक एक यूनिकोड कोडपॉइंट का प्रतिनिधित्व करता है। और एक कोडपॉइंट आवश्यक रूप से एक वर्ण को इंगित नहीं करता है।
इनक गमुस

यह जोड़ने के लिए कि "एक रूनी भी int32 के लिए एक उपनाम है" हाँ, लेकिन इसका मतलब यह नहीं है कि यह गरीब-आदमी संपीड़न के लिए उपयोगी है ... यदि आप 55296 की तरह कुछ हिट करते हैं तो स्ट्रिंग रूपांतरण भटक जाता है: Go Playground
kubanczyk

27

मेरे पास fabrizioM के उत्तर पर टिप्पणी पोस्ट करने के लिए पर्याप्त प्रतिष्ठा नहीं है , इसलिए मुझे इसे यहां पोस्ट करना होगा।

फैब्रीज़ियो का जवाब काफी हद तक सही है, और उन्होंने निश्चित रूप से समस्या का सार पकड़ लिया - हालांकि एक अंतर है जिसे बनाया जाना चाहिए।

एक स्ट्रिंग जरूरी रन का एक क्रम नहीं है। यह 'बाइट्स के स्लाइस' के ऊपर एक आवरण है, गो एरे के ऊपर एक रैपर होने के कारण एक स्लाइस । इससे क्या फर्क पड़ता है?

एक रूण प्रकार आवश्यक रूप से एक 32-बिट मान है, जिसका अर्थ है रन प्रकार के मूल्यों का एक क्रम में बिट्स की कुछ संख्या x * 32 होगी। स्ट्रिंग्स, बाइट्स का एक क्रम होने के बजाय, x * 8 बिट्स की लंबाई है। यदि सभी तार वास्तव में यूनिकोड में थे, तो इस अंतर का कोई प्रभाव नहीं पड़ेगा। चूंकि स्ट्रिंग्स बाइट्स के स्लाइस हैं , हालांकि, गो एएससीआईआई या किसी अन्य मनमाने बाइट एन्कोडिंग का उपयोग कर सकते हैं।

हालांकि, स्ट्रिंग शाब्दिकों को UTF-8 में एन्कोड किए गए स्रोत में लिखा जाना आवश्यक है।

जानकारी का स्रोत: http://blog.golang.org/strings


1
अच्छी बात ! प्रत्येक रनर को 4 बाइट्स की आवश्यकता होती है, लेकिन स्ट्रिंग में प्रत्येक वर्ण utf8 के साथ एन्कोडेड होता है, इस प्रकार 1 ~ 3 बाइट्स अधिक से अधिक होता है।
एरिक वांग

15

(एक लग रहा है कि उत्तर से ऊपर अभी भी मतभेद और के बीच संबंधों को राज्य नहीं था मिल गया stringऔर []runeबहुत स्पष्ट रूप से, तो मैं उदाहरण के साथ एक और जवाब जोड़ने का प्रयास करते हैं।)

जैसा कि @Strangeworkउत्तर में कहा गया है, stringऔर []runeचुप अलग हैं।

अंतर - stringऔर []rune:

  • string valueकेवल पढ़ने के लिए बाइट स्लाइस है। और, एक स्ट्रिंग शाब्दिक utf-8 में एन्कोडेड है। प्रत्येक चार stringवास्तव में 1 ~ 3 बाइट्स runeलेता है , जबकि प्रत्येक 4 बाइट्स लेता है
  • के लिए string, दोनों len()और सूचकांक बाइट्स पर आधारित हैं।
  • []runeदोनों के लिए , len()और इंडेक्स रूनी (या इंट 32) पर आधारित हैं।

रिश्ते - stringऔर []rune:

  • जब आप से परिवर्तित stringकरते हैं []rune, तो उस स्ट्रिंग में प्रत्येक utf-8 char एक बन जाता है rune
  • इसी तरह, रिवर्स रूपांतरण में, जब से परिवर्तित किया []runeजाता है string, प्रत्येक में runeएक utf-8 char बन जाता है 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()
}

निष्पादित:

go 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()स्ट्रिंग स्ट्रिंग पर आधारित है, इस प्रकार पहली पंक्ति मुद्रित होती हैlen: 11
    • चूंकि स्ट्रिंग पर सूचकांक भी बाइट्स पर आधारित होता है, इस प्रकार निम्न 2 लाइनें टाइप के मानों को प्रिंट करती हैं uint8(चूंकि byteएक अन्य प्रकार का प्रकार है uint8, जैसे कि)।
  • में परिवर्तित होने stringपर []rune, इसमें 7 utf8 वर्ण मिले, इस प्रकार 7 रन बने।

    • चूंकि len()पर []runeरूण पर आधारित है, इस प्रकार अंतिम पंक्ति मुद्रित len: 7
    • यदि आप []runeइंडेक्स के माध्यम से काम करते हैं , तो यह रनवे के आधार पर पहुंच जाएगा।
      चूँकि प्रत्येक भाग मूल स्ट्रिंग में utf8 char से होता है, इस प्रकार आप यह भी कह सकते हैं कि दोनों len()और index संचालन utf8 char पर []runeआधारित हैं।

"स्ट्रिंग के लिए, दोनों लेन () और सूचकांक बाइट्स पर आधारित हैं।" आप समझा सकते हैं कि थोड़ा और? जब मैं fmt.Println("hello你好"[0])इसे बाइट्स के बजाय वास्तविक UTF-8 कोड बिंदु देता हूं ।
जूलियन

@ जूलियन कृपया जवाब में कार्यक्रम के आउटपुट पर एक नज़र डालें s[0], इसके लिए , यह प्रिंट होता है s[0]: 104, type: uint8, प्रकार है uint8, इसका अर्थ है एक बाइट। ASCII चार्ट के लिए hutf-8 की तरह यह भी प्रतिनिधित्व करने के लिए एकल बाइट का उपयोग करता है, इसलिए कोड बिंदु एकल बाइट के समान है; लेकिन चीनी वर्ण जैसे , यह 3 बाइट्स का उपयोग करता है।
एरिक वैंग

स्पष्ट करने वाला उदाहरण। मैंने आपको यहां stackoverflow.com/a/62739051/12817546 उद्धृत किया है ।
टॉम जे

7

बाकी सभी ने रनों से संबंधित भाग को कवर किया है, इसलिए मैं इसके बारे में बात नहीं करने जा रहा हूं।

हालांकि, switchकोई तर्क नहीं होने से संबंधित एक प्रश्न भी है। यह सिर्फ इसलिए है क्योंकि गोलंग में, switchअभिव्यक्ति के बिना एक वैकल्पिक तरीका है अगर / और तर्क। उदाहरण के लिए, यह लिखना:

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")
}

आप यहां और पढ़ सकते हैं ।


0

एक रूण एक int32 मान है, और इसलिए यह एक गो प्रकार है जिसका उपयोग यूनिकोड कोड बिंदु का प्रतिनिधित्व करने के लिए किया जाता है। यूनिकोड कोड पॉइंट या कोड स्थिति एक संख्यात्मक मान है जो आमतौर पर सिंगल यूनिकोड वर्णों का प्रतिनिधित्व करने के लिए उपयोग किया जाता है;

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.