Как форматируются строки в Golang?

1,881 views
Skip to first unread message

sys_dev

unread,
Dec 29, 2013, 5:51:34 AM12/29/13
to gola...@googlegroups.com
Доброе, $(ВремяСуток)!

Мне не совсем понятно как правильно форматировать строки?

Допустим есть код:

func printTitle(srcFilename, dstFilename string) {
fmt.Printf("\tSource: %s\n", srcFilename)
fmt.Printf("\tResult: %s\n", dstFilename)
}

Хочется две не-атомарные записи строк превратить в один fmt.Println() из этого вытекает вывод о том, что нужно как-то сформатировать одну большую строку.
Как это сделать?

Пока мои мысли крутятся вокруг fmt.Print(), fmt.Printf() которым можно подать io.Writer , но какой пока не понятно?

Я как понимаю надо пытаться создать буфер, а его обернуть в какой-нить Writer у которого можно прочитать string.

Но как это сделать пока не представляю, чтение доки пока не учит ничему )

sys_dev

unread,
Dec 29, 2013, 6:02:53 AM12/29/13
to gola...@googlegroups.com
UPD:

Кое-что понял, есть bytes,в котором можно поступить как в example к Buffer:
это единственный путь или есть более удобный вариант?

воскресенье, 29 декабря 2013 г., 14:51:34 UTC+4 пользователь sys_dev написал:

Alexey Palazhchenko

unread,
Dec 29, 2013, 7:55:54 AM12/29/13
to gola...@googlegroups.com
>
> func printTitle(srcFilename, dstFilename string) {
> fmt.Printf("\tSource: %s\n", srcFilename)
> fmt.Printf("\tResult: %s\n", dstFilename)
> }
>
> Хочется две не-атомарные записи строк превратить в один fmt.Println() из этого вытекает вывод о том, что нужно как-то сформатировать одну большую строку.

Просто передать несколько аргументов: fmt.Printf("\tSource: %s\n\tResult: %s\n, srcFilename, dstFilename)

Только не называйте это атомарностью.

–-–
Алексей "AlekSi" Палажченко

Dmitry Vyukov

unread,
Dec 29, 2013, 8:46:04 AM12/29/13
to gola...@googlegroups.com
Еще есть fmt.Sprintf().




2013/12/29 sys_dev <ntvis...@gmail.com>:
> --
> Вы получили это сообщение, поскольку подписаны на группу GoLang Russian.
>
> Чтобы отказаться от подписки на эту группу и перестать получать из нее
> сообщения, отправьте электронное письмо на адрес
> golang-ru+...@googlegroups.com.
> Настройки подписки и доставки писем:
> https://groups.google.com/groups/opt_out.

sys_dev

unread,
Dec 29, 2013, 9:34:28 AM12/29/13
to gola...@googlegroups.com
Вы неверно поняли, что я называю "атомарностью" в моем первом посте.
В виду многопоточности программ и глобальных STDOUT, STDERR запись строк не должна быть разбитой на несколько printf()-подобных вызовов, а только один printf(). Поэтому и стремлюсь написать удобный код по сборке одной большой строки, для ее записи с помощью fmt.Printf().

пока написал так:

func printTitle(srcFilename, dstFilename string) {
var buf bytes.Buffer
fmt.Fprintln(&buf, "Program parameters")
dir := filepath.Dir(srcFilename)
fmt.Fprintf(&buf, "\tWork dir: \"%s\"\n", dir)
if name, err := filepath.Rel(dir, srcFilename); err == nil {
fmt.Fprintf(&buf, "\tSource: %s\n", name)
}
if name, err := filepath.Rel(dir, dstFilename); err == nil {
fmt.Fprintf(&buf, "\tResult: %s\n", name)
}
fmt.Println(buf.String())
}

работает, но очень громоздко! ;(((

воскресенье, 29 декабря 2013 г., 16:55:54 UTC+4 пользователь Alexey Palazhchenko написал:

Dmitry Vyukov

unread,
Dec 29, 2013, 9:49:18 AM12/29/13
to gola...@googlegroups.com
2013/12/29 sys_dev <ntvis...@gmail.com>:
> Вы неверно поняли, что я называю "атомарностью" в моем первом посте.
> В виду многопоточности программ и глобальных STDOUT, STDERR запись строк не
> должна быть разбитой на несколько printf()-подобных вызовов, а только один
> printf(). Поэтому и стремлюсь написать удобный код по сборке одной большой
> строки, для ее записи с помощью fmt.Printf().
>
> пока написал так:
>
> func printTitle(srcFilename, dstFilename string) {
> var buf bytes.Buffer
> fmt.Fprintln(&buf, "Program parameters")
> dir := filepath.Dir(srcFilename)
> fmt.Fprintf(&buf, "\tWork dir: \"%s\"\n", dir)
> if name, err := filepath.Rel(dir, srcFilename); err == nil {
> fmt.Fprintf(&buf, "\tSource: %s\n", name)
> }
> if name, err := filepath.Rel(dir, dstFilename); err == nil {
> fmt.Fprintf(&buf, "\tResult: %s\n", name)
> }
> fmt.Println(buf.String())
> }
>
> работает, но очень громоздко! ;(((
>

Громоздкость тут в основном не из-за вывода в буфер.

fmt.Println точно не атомарно добавляет перевод строки.

sys_dev

unread,
Dec 29, 2013, 11:11:53 AM12/29/13
to gola...@googlegroups.com
Слазил в %GOROOT%\src\pkg\fmt\print.go

// Fprintln formats using the default formats for its operands and writes to w.
// Spaces are always added between operands and a newline is appended.
// It returns the number of bytes written and any write error encountered.
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
p := newPrinter()
p.doPrint(a, true, true)
n, err = w.Write(p.buf)
p.free()
return
}

Вроде как атомарно одна w.Write()!

А из-за чего громоздкость, что еще можно сделать чтобы стало лучше? ;)

воскресенье, 29 декабря 2013 г., 18:49:18 UTC+4 пользователь Dmitry Vyukov написал:

Dmitry Vyukov

unread,
Dec 29, 2013, 11:22:37 AM12/29/13
to gola...@googlegroups.com
2013/12/29 sys_dev <ntvis...@gmail.com>:
> Слазил в %GOROOT%\src\pkg\fmt\print.go
>
> // Fprintln formats using the default formats for its operands and writes to
> w.
> // Spaces are always added between operands and a newline is appended.
> // It returns the number of bytes written and any write error encountered.
> func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
> p := newPrinter()
> p.doPrint(a, true, true)
> n, err = w.Write(p.buf)
> p.free()
> return
> }
>
> Вроде как атомарно одна w.Write()!

Точно!
Меня смутило вот это:

func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
...
if addnewline {
p.buf.WriteByte('\n')
}
}

Но это внутренний буфер.


> А из-за чего громоздкость, что еще можно сделать чтобы стало лучше? ;)

fmt.Printf("Program parameters\n\tWork dir: '%s'\n\tSource:
'%s'\n\tResult: '%s'\n", filepath.Dir(src), src, dst)
Reply all
Reply to author
Forward
0 new messages