هل تعجبك تطبيقات CLI؟لا تفوتlolcatالبرنامج التعليمي كذلك!
كوزايهو أحد تلك التطبيقات التي لا يمكنك العيش بدونها.
يقوم بشكل أساسي بإنشاء صور ASCII للبقرة مع أي رسالة تقوم بتمريرها إليها ، في لقطة الشاشة أعلاه باستخدامfortune
لتوليدها. لكنها لا تقتصر على مجال الأبقار ، يمكنها طباعة طيور البطريق والمووس والعديد من الحيوانات الأخرى.
يبدو أنه تطبيق مفيد للتنقل إلى Go!
أيضًا ، أحب ترخيص اللغة الإنجليزية العادي المرفق به:
==============
cowsay License
==============
cowsay is distributed under the same licensing terms as Perl: the
Artistic License or the GNU General Public License. If you don’t
want to track down these licenses and read them for yourself, use
the parts that I’d prefer:
(0) I wrote it and you didn’t.
(1) Give credit where credit is due if you borrow the code for some
other purpose.
(2) If you have any bugfixes or suggestions, please notify me so
that I may incorporate them.
(3) If you try to make money off of cowsay, you suck.
لنبدأ بتحديد المشكلة. نريد أن نقبل المدخلات من خلال أنبوب ، ونطلب من بقرتنا أن تقول ذلك.
يقرأ التكرار الأول إدخال المستخدم من الأنبوب ويطبعه مرة أخرى. ليست معقدة للغاية.
package main
import (
“bufio”
“fmt”
“io”
“os”
)
func main() {
info, _ := os.Stdin.Stat()
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Mode</span>()<span style="color:#f92672">&</span><span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">ModeCharDevice</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"The command is intended to work with pipes."</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"Usage: fortune | gocowsay"</span>)
<span style="color:#66d9ef">return</span>
}
<span style="color:#a6e22e">reader</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">bufio</span>.<span style="color:#a6e22e">NewReader</span>(<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stdin</span>)
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">output</span> []<span style="color:#66d9ef">rune</span>
<span style="color:#66d9ef">for</span> {
<span style="color:#a6e22e">input</span>, <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">reader</span>.<span style="color:#a6e22e">ReadRune</span>()
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> <span style="color:#f92672">&&</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">io</span>.<span style="color:#a6e22e">EOF</span> {
<span style="color:#66d9ef">break</span>
}
<span style="color:#a6e22e">output</span> = append(<span style="color:#a6e22e">output</span>, <span style="color:#a6e22e">input</span>)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">j</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">j</span> < len(<span style="color:#a6e22e">output</span>); <span style="color:#a6e22e">j</span><span style="color:#f92672">++</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"%c"</span>, <span style="color:#a6e22e">output</span>[<span style="color:#a6e22e">j</span>])
}
}
نحن نفتقد البقرة ، ونحتاج أيضًا إلى لف الرسالة في بالون منسق جيدًا.
هذا هو التكرار الأول لبرنامجنا:
package main
import (
“bufio”
“fmt”
“io”
“os”
“strings”
“unicode/utf8”
)
// buildBalloon takes a slice of strings of max width maxwidth
// prepends/appends margins on first and last line, and at start/end of each line
// and returns a string with the contents of the balloon
func buildBalloon(lines []string, maxwidth int) string {
var borders []string
count := len(lines)
var ret []string
<span style="color:#a6e22e">borders</span> = []<span style="color:#66d9ef">string</span>{<span style="color:#e6db74">"/"</span>, <span style="color:#e6db74">"\\"</span>, <span style="color:#e6db74">"\\"</span>, <span style="color:#e6db74">"/"</span>, <span style="color:#e6db74">"|"</span>, <span style="color:#e6db74">"<"</span>, <span style="color:#e6db74">">"</span>}
<span style="color:#a6e22e">top</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">" "</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Repeat</span>(<span style="color:#e6db74">"_"</span>, <span style="color:#a6e22e">maxwidth</span><span style="color:#f92672">+</span><span style="color:#ae81ff">2</span>)
<span style="color:#a6e22e">bottom</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">" "</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Repeat</span>(<span style="color:#e6db74">"-"</span>, <span style="color:#a6e22e">maxwidth</span><span style="color:#f92672">+</span><span style="color:#ae81ff">2</span>)
<span style="color:#a6e22e">ret</span> = append(<span style="color:#a6e22e">ret</span>, <span style="color:#a6e22e">top</span>)
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">count</span> <span style="color:#f92672">==</span> <span style="color:#ae81ff">1</span> {
<span style="color:#a6e22e">s</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">"%s %s %s"</span>, <span style="color:#a6e22e">borders</span>[<span style="color:#ae81ff">5</span>], <span style="color:#a6e22e">lines</span>[<span style="color:#ae81ff">0</span>], <span style="color:#a6e22e">borders</span>[<span style="color:#ae81ff">6</span>])
<span style="color:#a6e22e">ret</span> = append(<span style="color:#a6e22e">ret</span>, <span style="color:#a6e22e">s</span>)
} <span style="color:#66d9ef">else</span> {
<span style="color:#a6e22e">s</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">`%s %s %s`</span>, <span style="color:#a6e22e">borders</span>[<span style="color:#ae81ff">0</span>], <span style="color:#a6e22e">lines</span>[<span style="color:#ae81ff">0</span>], <span style="color:#a6e22e">borders</span>[<span style="color:#ae81ff">1</span>])
<span style="color:#a6e22e">ret</span> = append(<span style="color:#a6e22e">ret</span>, <span style="color:#a6e22e">s</span>)
<span style="color:#a6e22e">i</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">1</span>
<span style="color:#66d9ef">for</span> ; <span style="color:#a6e22e">i</span> < <span style="color:#a6e22e">count</span><span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span> {
<span style="color:#a6e22e">s</span> = <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">`%s %s %s`</span>, <span style="color:#a6e22e">borders</span>[<span style="color:#ae81ff">4</span>], <span style="color:#a6e22e">lines</span>[<span style="color:#a6e22e">i</span>], <span style="color:#a6e22e">borders</span>[<span style="color:#ae81ff">4</span>])
<span style="color:#a6e22e">ret</span> = append(<span style="color:#a6e22e">ret</span>, <span style="color:#a6e22e">s</span>)
}
<span style="color:#a6e22e">s</span> = <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">`%s %s %s`</span>, <span style="color:#a6e22e">borders</span>[<span style="color:#ae81ff">2</span>], <span style="color:#a6e22e">lines</span>[<span style="color:#a6e22e">i</span>], <span style="color:#a6e22e">borders</span>[<span style="color:#ae81ff">3</span>])
<span style="color:#a6e22e">ret</span> = append(<span style="color:#a6e22e">ret</span>, <span style="color:#a6e22e">s</span>)
}
<span style="color:#a6e22e">ret</span> = append(<span style="color:#a6e22e">ret</span>, <span style="color:#a6e22e">bottom</span>)
<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Join</span>(<span style="color:#a6e22e">ret</span>, <span style="color:#e6db74">"\n"</span>)
}
// tabsToSpaces converts all tabs found in the strings
// found in the lines
slice to 4 spaces, to prevent misalignments in
// counting the runes
func tabsToSpaces(lines []string) []string {
var ret []string
for _, l := range lines {
l = strings.Replace(l, “\t”, " ", -1)
ret = append(ret, l)
}
return ret
}
// calculatemaxwidth given a slice of strings returns the length of the
// string with max length
func calculateMaxWidth(lines []string) int {
w := 0
for _, l := range lines {
len := utf8.RuneCountInString(l)
if len > w {
w = len
}
}
<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">w</span>
}
// normalizeStringsLength takes a slice of strings and appends
// to each one a number of spaces needed to have them all the same number
// of runes
func normalizeStringsLength(lines []string, maxwidth int) []string {
var ret []string
for _, l := range lines {
s := l + strings.Repeat(" ", maxwidth-utf8.RuneCountInString(l))
ret = append(ret, s)
}
return ret
}
func main() {
info, _ := os.Stdin.Stat()
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Mode</span>()<span style="color:#f92672">&</span><span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">ModeCharDevice</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"The command is intended to work with pipes."</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"Usage: fortune | gocowsay"</span>)
<span style="color:#66d9ef">return</span>
}
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">lines</span> []<span style="color:#66d9ef">string</span>
<span style="color:#a6e22e">reader</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">bufio</span>.<span style="color:#a6e22e">NewReader</span>(<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stdin</span>)
<span style="color:#66d9ef">for</span> {
<span style="color:#a6e22e">line</span>, <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">reader</span>.<span style="color:#a6e22e">ReadLine</span>()
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> <span style="color:#f92672">&&</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">io</span>.<span style="color:#a6e22e">EOF</span> {
<span style="color:#66d9ef">break</span>
}
<span style="color:#a6e22e">lines</span> = append(<span style="color:#a6e22e">lines</span>, string(<span style="color:#a6e22e">line</span>))
}
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">cow</span> = <span style="color:#e6db74">` \ ^__^
\ (oo)_______
(__)\ )/
||----w |
|| ||
`
<span style="color:#a6e22e">lines</span> = <span style="color:#a6e22e">tabsToSpaces</span>(<span style="color:#a6e22e">lines</span>)
<span style="color:#a6e22e">maxwidth</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">calculateMaxWidth</span>(<span style="color:#a6e22e">lines</span>)
<span style="color:#a6e22e">messages</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">normalizeStringsLength</span>(<span style="color:#a6e22e">lines</span>, <span style="color:#a6e22e">maxwidth</span>)
<span style="color:#a6e22e">balloon</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">buildBalloon</span>(<span style="color:#a6e22e">messages</span>, <span style="color:#a6e22e">maxwidth</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">balloon</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">cow</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>()
}
دعنا الآن نجعل الشكل قابلاً للتكوين بإضافة aستيجوسورس
يستخدم التطبيق الأصلي ملف-f
علم لقبول شخصية مخصصة. لذلك دعونا نفعل الشيء نفسهمعالجة علامة سطر الأوامر.
أقوم بتغيير البرنامج السابق لفترة وجيزة لتقديمهprintFigure()
// printFigure given a figure name prints it.
// Currently accepts `cow` and `stegosaurus`.
func printFigure(name string) {
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">cow</span> = <span style="color:#e6db74">` \ ^__^
\ (oo)_______
(__)\ )/
||----w |
|| ||
`
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">stegosaurus</span> = <span style="color:#e6db74">` \ . .
\ / </span> <span style="color:#f92672">+</span> <span style="color:#e6db74">"
" + . .' " </span><span style="color:#e6db74"> \ .---. < > < > .---. </span><span style="color:#e6db74"> \ | \ \ - ~ ~ - / / | </span><span style="color:#e6db74"> _____ ..-~ ~-..-~ </span><span style="color:#e6db74"> | | \~~~\\.'
+ ""</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">
./~/
--------- _/ _/
.’ O \ / / \ "
(_____, </span> <span style="color:#f92672">+</span> <span style="color:#e6db74">"
" + ._.' | } \/~~~/ </span><span style="color:#e6db74">
+ ""</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">
----. / } | / __/
</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">"
" + -. | / | /
+ ""</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">
. ,|
~-.| /_ - ~ ^| /- _ </span> <span style="color:#f92672">+</span> <span style="color:#e6db74">"
" + ..-' </span><span style="color:#e6db74"> | / | / ~-.
+ ""</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">
-. _ _ _
|| |__| ~ - . _ _ _ _ _>
`
<span style="color:#66d9ef">switch</span> <span style="color:#a6e22e">name</span> {
<span style="color:#66d9ef">case</span> <span style="color:#e6db74">"cow"</span>:
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">cow</span>)
<span style="color:#66d9ef">case</span> <span style="color:#e6db74">"stegosaurus"</span>:
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">stegosaurus</span>)
<span style="color:#66d9ef">default</span>:
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"Unknown figure"</span>)
}
}
ومتغيرةmain()
لقبول العلم وتمريره إليهprintFigure()
:
func main() {
//...
var figure string
flag.StringVar(&figure, "f", "cow", "the figure name. Valid values are `cow` and `stegosaurus`")
flag.Parse()
<span style="color:#75715e">//...
printFigure(figure)
fmt.Println()
}
أعتقد أننا في مرحلة جيدة. أريد فقط أن أجعل هذا النظام قابلاً للاستخدام ، بدون تشغيلgo run main.go
، لذلك سأكتب فقطgo build
وgo install
.
يمكنني الآن قضاء اليوم معجلولكاتو gocowsay
المزيد من دروس Go:
- استخدام وكيل NGINX العكسي لخدمة خدمات Go
- عمل نسخة من هيكل في Go
- أساسيات Go Web Server
- فرز نوع الخريطة في Go
- الذهاب المؤشرات باختصار
- وأوضح Go Tags
- الذهاب تنسيق التاريخ والوقت
- معالجة JSON باستخدام Go
- وظائف متنوعة
- ورقة الغش Go Strings
- شرح واجهة Go Empty
- تصحيح الأخطاء الذهاب مع VS Code و Delve
- تقوم Named Go بإرجاع المعلمات
- توليد أرقام وسلاسل عشوائية في Go
- بنية نظام الملفات لمشروع Go
- تم تنفيذ خوارزمية البحث الثنائي في Go
- استخدام إشارات سطر الأوامر في Go
- أوضح جوباته
- أنشئ تطبيق Command Line باستخدام Go: lolcat
- إنشاء أمر CLI باستخدام Go: cowsay
- استخدام أنابيب شل مع Go
- Go CLI التعليمي: Fortune clone
- ضع قائمة بالملفات في مجلد باستخدام Go
- استخدم Go للحصول على قائمة بالمستودعات من GitHub
- اذهب ، قم بإلحاق شريحة من السلاسل بملف
- اذهب ، قم بتحويل سلسلة إلى شريحة بايت
- تصور مساهمات Git المحلية الخاصة بك مع Go
- الشروع في استخدام Go CPU وتوصيف الذاكرة
- حل الخطأ "لا يدعم الفهرسة" في برنامج Go
- قياس وقت التنفيذ في برنامج Go
- بناء زاحف الويب باستخدام Go لاكتشاف العناوين المكررة
- Go Best Practices: المؤشر أم مستقبلات القيمة؟
- Go Best Practices: هل يجب عليك استخدام طريقة أم دالة؟
- Go Data Structures: Set
- ورقة الغش في خرائط Go
- إنشاء تطبيقات لأنواع عامة في Go
- Go Data Structures: القاموس
- Go هياكل البيانات: Hash Table
- تنفيذ مستمعي الأحداث في الانتقال عبر القنوات
- Go Data Structures: Stack
- Go هياكل البيانات: قائمة الانتظار
- Go Data Structures: Binary Search Tree
- Go هياكل البيانات: رسم بياني
- Go Data Structures: قائمة مرتبطة
- الدليل الكامل إلى Go Data Structures
- مقارنة قيم Go
- هل Go موجه للكائن؟
- العمل مع قاعدة بيانات SQL في Go
- استخدام متغيرات البيئة في Go
- Go البرنامج التعليمي: REST API مدعوم من PostgreSQL
- تمكين CORS على خادم Go Web
- نشر تطبيق Go في حاوية Docker
- لماذا Go هي لغة قوية للتعلم كمطور PHP
- اذهب ، قم بإزالة io.Reader.ReadString حرف سطر جديد
- اذهب ، كيف تراقب التغييرات وتعيد بناء برنامجك
- اذهب وعد الأشهر منذ تاريخ
- الوصول إلى معلمات HTTP POST في Go