मुद्रण के बिना एक गो स्ट्रिंग प्रारूपित करें?


381

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

मैं कर सकता हूँ:

bar := "bar"
fmt.Printf("foo: %s", bar)

लेकिन मैं चाहता हूं कि मुद्रित के बजाय स्वरूपित स्ट्रिंग लौटाया जाए ताकि मैं इसे और अधिक हेरफेर कर सकूं।

मैं भी कुछ ऐसा कर सकता था:

s := "foo: " + bar

लेकिन यह तब पढ़ना मुश्किल हो जाता है जब प्रारूप स्ट्रिंग जटिल होता है, और बोझिल तब होता है जब एक या कई हिस्से तार नहीं होते हैं और उन्हें पहले बदलना पड़ता है, जैसे

i := 25
s := "foo: " + strconv.Itoa(i)

क्या ऐसा करने का एक सरल तरीका है?

जवाबों:


465

स्प्रिंटफ वह है जो आप ढूंढ रहे हैं।

उदाहरण

fmt.Sprintf("foo: %s", bar)

आप इसे "ए टूर ऑफ़ गो" के भाग के रूप में त्रुटिपूर्ण उदाहरण में उपयोग में देख सकते हैं ।

return fmt.Sprintf("at %v, %s", e.When, e.What)

6
% बात के बाद पत्र करता है? क्या यह% y और% q हो सकता है? या% y और% y
फिलिप बार्टुज़ि

17
पत्र मायने रखता है, इसे एक क्रिया कहा जाता है, मूल रूप से यह स्प्रिंटफ को यह जानने देता है कि चर किस प्रकार का है ताकि अगर यह 65 प्राप्त हो और क्रिया% d है तो यह संख्या 65 को प्रिंट करेगा लेकिन यदि क्रिया% c है तो यह वर्ण को प्रिंट करेगा 'ए'। देखें: golang.org/pkg/fmt/#hdr-Printing
redsalt

2
इसे स्प्रिंटफ क्यों कहा जाता है? एस के लिए स्ट्रिंग, प्रारूप के लिए एफ? यह अजीब है कि यदि फ़ंक्शन स्क्रीन पर आउटपुट नहीं करता है तो प्रिंट फ़ंक्शन नाम का हिस्सा है। इसने मुझे थोड़ी देर के लिए परेशान कर दिया है ...
जेकलूम

194

1. सरल तार

"सरल" तार के लिए (आमतौर पर एक पंक्ति में जो फिट बैठता है) सबसे सरल समाधान का उपयोग कर रहा है fmt.Sprintf()और दोस्तों ( fmt.Sprint(), fmt.Sprintln())। ये स्टार्टर Sअक्षर के बिना फ़ंक्शन के अनुरूप हैं , लेकिन ये Sxxx()वेरिएंट stringमानक आउटपुट पर प्रिंट करने के बजाय परिणाम लौटाते हैं ।

उदाहरण के लिए:

s := fmt.Sprintf("Hi, my name is %s and I'm %d years old.", "Bob", 23)

चर sको मूल्य के साथ आरंभीकृत किया जाएगा:

Hi, my name is Bob and I'm 23 years old.

युक्ति: यदि आप विभिन्न प्रकारों के मानों को संक्षिप्त करना चाहते हैं, तो आपको स्वचालित रूप से उपयोग करने की आवश्यकता नहीं होगी Sprintf()(जिसे प्रारूप स्ट्रिंग की आवश्यकता होती है) जैसा Sprint()कि यह वास्तव में करता है। इस उदाहरण को देखें:

i := 23
s := fmt.Sprint("[age:", i, "]") // s will be "[age:23]"

केवल stringएस को समाप्‍त करने के लिए , आप भी उपयोग strings.Join()कर सकते हैं जहां आप एक कस्टम विभाजक निर्दिष्ट कर सकते हैं string(शामिल होने के लिए तार के बीच रखा जा सकता है)।

गो प्ले ग्राउंड पर इन्हें आज़माएं ।

2. जटिल तार (दस्तावेज)

यदि आप जिस स्ट्रिंग को बनाने की कोशिश कर रहे हैं वह अधिक जटिल है (उदाहरण के लिए एक बहु-पंक्ति ईमेल संदेश), fmt.Sprintf()कम पठनीय और कम कुशल हो जाती है (विशेषकर यदि आपको ऐसा कई बार करना पड़ता है)।

इसके लिए मानक पुस्तकालय संकुल प्रदान करता है text/templateऔर html/template। ये पैकेज टेक्स्ट-आउटपुट जेनरेट करने के लिए डेटा-संचालित टेम्प्लेट को लागू करते हैं। html/templateकोड इंजेक्शन के खिलाफ सुरक्षित HTML आउटपुट उत्पन्न करने के लिए है। यह पैकेज के रूप में एक ही इंटरफ़ेस प्रदान करता है text/templateऔर text/templateजब भी आउटपुट HTML होता है तो इसके बजाय इसका उपयोग किया जाना चाहिए ।

templateमूल रूप से पैकेजों का उपयोग करने के लिए आपको एक stringमूल्य के रूप में एक स्थिर टेम्पलेट प्रदान करना पड़ता है (जो किसी फ़ाइल से उत्पन्न हो सकता है, जिस स्थिति में आप केवल फ़ाइल नाम प्रदान करते हैं) जिसमें स्थैतिक पाठ हो सकता है, और जब संसाधित और निष्पादित की जाती हैं, तो कार्रवाई हो सकती है इंजन टेम्पलेट को प्रोसेस करता है और आउटपुट उत्पन्न करता है।

आप ऐसे पैरामीटर प्रदान कर सकते हैं जो स्थिर टेम्पलेट में शामिल / प्रतिस्थापित हैं और जो आउटपुट जनरेशन प्रक्रिया को नियंत्रित कर सकते हैं। ऐसे मापदंडों का विशिष्ट रूप structएस और mapमूल्य हैं जिन्हें नेस्टेड किया जा सकता है।

उदाहरण:

उदाहरण के लिए मान लें कि आप इस तरह दिखने वाले ईमेल संदेश उत्पन्न करना चाहते हैं:

Hi [name]!

Your account is ready, your user name is: [user-name]

You have the following roles assigned:
[role#1], [role#2], ... [role#n]

इस तरह से ईमेल संदेश निकाय बनाने के लिए, आप निम्नलिखित स्थैतिक टेम्पलेट का उपयोग कर सकते हैं:

const emailTmpl = `Hi {{.Name}}!

Your account is ready, your user name is: {{.UserName}}

You have the following roles assigned:
{{range $i, $r := .Roles}}{{if $i}}, {{end}}{{.}}{{end}}
`

और इसे निष्पादित करने के लिए इस तरह डेटा प्रदान करें:

data := map[string]interface{}{
    "Name":     "Bob",
    "UserName": "bob92",
    "Roles":    []string{"dbteam", "uiteam", "tester"},
}

आम तौर पर टेम्प्लेट का आउटपुट io.Writerए के लिए लिखा जाता है , इसलिए यदि आप परिणाम के रूप में चाहते हैं, तो stringbytes.Buffer(जो लागू होता है io.Writer) बनाएं और लिखें । टेम्पलेट को निष्पादित करना और परिणाम प्राप्त करना string:

t := template.Must(template.New("email").Parse(emailTmpl))
buf := &bytes.Buffer{}
if err := t.Execute(buf, data); err != nil {
    panic(err)
}
s := buf.String()

यह अपेक्षित आउटपुट में परिणाम देगा:

Hi Bob!

Your account is ready, your user name is: bob92

You have the following roles assigned:
dbteam, uiteam, tester

इसे गो प्लेग्राउंड पर आज़माएं ।

यह भी ध्यान रखें कि जाओ 1.10, के बाद से एक नए, तेजी से, अधिक विशेष विकल्प उपलब्ध है bytes.Bufferजो है: strings.Builder। उपयोग बहुत समान है:

builder := &strings.Builder{}
if err := t.Execute(builder, data); err != nil {
    panic(err)
}
s := builder.String()

इस एक को खेल के मैदान पर आज़माएं ।

नोट: यदि आप os.Stdoutलक्ष्य के रूप में प्रदान करते हैं (जो भी लागू होता है io.Writer) तो आप टेम्पलेट निष्पादन का परिणाम भी प्रदर्शित कर सकते हैं :

t := template.Must(template.New("email").Parse(emailTmpl))
if err := t.Execute(os.Stdout, data); err != nil {
    panic(err)
}

यह सीधे परिणाम को लिखेगा os.Stdout। इसे गो प्लेग्राउंड पर आज़माएं ।


2

आपके मामले में, आपको प्रारूप स्ट्रिंग के लिए स्प्रिंटफ () का उपयोग करने की आवश्यकता है।

func Sprintf(format string, a ...interface{}) string

स्प्रिंटफ प्रारूप के अनुसार एक प्रारूप निर्दिष्ट करता है और परिणामी स्ट्रिंग लौटाता है।

s := fmt.Sprintf("Good Morning, This is %s and I'm living here from last %d years ", "John", 20)

आपका आउटपुट होगा:

गुड मॉर्निंग, दिस इज जॉन और मैं पिछले 20 सालों से यहां रह रहा हूं।


0

fmt.SprintF फ़ंक्शन एक स्ट्रिंग लौटाता है और आप स्ट्रिंग को उसी तरह प्रारूपित कर सकते हैं जिस तरह से आपके पास fmt.PrintF होगा।


0

हम कस्टम एक के माध्यम से नई स्ट्रिंग प्रकार कर सकते हैं define new Typeके साथ Formatसमर्थन करते हैं।

package main

import (
    "fmt"
    "text/template"
    "strings"
)

type String string
func (s String) Format(data map[string]interface{}) (out string, err error) {
    t := template.Must(template.New("").Parse(string(s)))
    builder := &strings.Builder{}
    if err = t.Execute(builder, data); err != nil {
        return
    }
    out = builder.String()
    return
}


func main() {
    const tmpl = `Hi {{.Name}}!  {{range $i, $r := .Roles}}{{if $i}}, {{end}}{{.}}{{end}}`
    data := map[string]interface{}{
        "Name":     "Bob",
        "Roles":    []string{"dbteam", "uiteam", "tester"},
    }

    s ,_:= String(tmpl).Format(data)
    fmt.Println(s)
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.