diff --git a/.gitignore b/.gitignore index 4782776c..d7b2930e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ _book .DS_Store .gitignore .vscode -.git \ No newline at end of file +.git +/fa/working \ No newline at end of file diff --git a/LANGS.md b/LANGS.md index 28c6ebd4..a7a4b0e6 100644 --- a/LANGS.md +++ b/LANGS.md @@ -8,3 +8,4 @@ * [বাংলা](bn/) * [日本語](ja/) * [中文](zh/) +* [پارسی](fa/) diff --git a/README.md b/README.md index 08115c99..09175656 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ * [বাংলা](bn/preface.md) * [日本語](ja/preface.md) * [中文](zh/preface.md) +* [پارسی](fa/preface.md) # Donate diff --git a/fa/01.0.md b/fa/01.0.md new file mode 100644 index 00000000..4e3a827d --- /dev/null +++ b/fa/01.0.md @@ -0,0 +1,24 @@ +
+ +# ۱- پیکربندی محیط Go + +به دنیای Go خوش آمدید. وقت آن است که در این دنیای جدید کمی به گشت و گذار بپردازیم! + +Go یکی از زبان های برنامه نویسی رایج می باشد که از قابلیت کامپایل سریع، سیستم های همزمان، و گاربیج کالکتور برخوردار است و همچنین دارای مزایای زیر می باشد: + +- یک پروژه بزرگ را تنها در چند ثانیه کامپایل می کند. +- یک مدل توسعه ی نرم افزاری فراهم می کند که استدلال در آن آسان است و بدین ترتیب از مشکلاتی که در هدر فایل های سبک C وجود داشت، جلوگیری می کند. +- یک زبان ایستا می باشد که در سیستم خود از داشتن سطوح مختلف خودداری کرده است، بنابراین نیازی نیست که کاربران زمان خود را برای درک ارتباط بین نوع ها سپری کنند. این زبان بیشتر شبیه یک زبان شیءگرای سبک می باشد. +- این زبان مجهز به GC یا گاربیج کالکتور می باشد و از ویژگی های همزمانی و ارتباط برخوردار می باشد. +- این زبان برای کامپیوترهایی که به چند هسته مجهز هستند، طراحی شده است. + +Go یک زبان برنامه نویسی کامپایلری است. در این زبان کارایی زبان های پویا یا مفسری در کنار امنیت زبان های ایستا هر دو با هم وجود دارند. این زبان برای کامپیوترهای مدرن و مجهز به چند هسته طراحی شده است که در شبکه هم کاربرد دارد. برای رسیدن به این اهداف، یک سری مسائل هستند که ذاتا باید در سطح انتخاب زبان برنامه نویسی حل شوند؛ برای مثال، یک سیستم سبک وزن کاملا رسا، یک مدل همروندی بومی، و یک گاربیج کالکتوری که به شدت تنظیم شده باشد. برای مدتی طولانی، هیچ بسته یا ابزاری برای رفع همه ی این مسائل معرفی نشد، تا زمانی که انگیزه ای برای توسعه ی زبان Go پدید آمد. + +در این فصل، نحوه نصب و پیکربندی محیط توسعه ی Go را بیان خواهم کرد. + +## لینک ها + +- [فهرست مطالب](preface.md) +- بخش بعدی: [نصب](01.1.md) + +
\ No newline at end of file diff --git a/fa/01.1.md b/fa/01.1.md new file mode 100644 index 00000000..3f1f21dc --- /dev/null +++ b/fa/01.1.md @@ -0,0 +1,199 @@ +
+ +# ۱-۱ نصب + +## سه روش برای نصب Go + +راه های زیادی برای تنظیم محیز توسعه ی Go بر روی کامپیوتر وجود دارند، و شما می توانید از هر یک از این روش ها به دلخواه خود استفاده کنید. به طور کلی سه روش زیر، به عنوان رایج ترین روش ها شناخته می شوند: + +- نصب پکیج های رسمی. + - تیم توسعه ی Go پکیج های جامعی را برای ویندوز، لینوکس، مک و سایر سیستم عامل ها فراهم کرده است. این روش نصب، شاید ساده ترین روش ممکن برای شروع باشد. شما می توانید به [صفحه ی دانلود Golang](https://golang.org/dl/) مراجعه کرده و فایل نصبی مورد نظر خود را دانلود کنید. +- نصب Go از طریق کد منبع. + - این روش بین توسعه دهندگان سیستم های شبه یونیکس مرسوم و شناخته شده است. +- استفاده از ابزارهای شخص سوم (third-party) + - ابزارها و پکیج های زیادی برای نصب Go وجود دارند، که شما می توانید از آن ها استفاده کنید. برای مثال apt-get در اوبونتو و homebrew در مک. + +اگر به هر دلیلی احتیاح دارید بیشتر از یک نسخه از Go را بر روی یک کامپیوتر داشته باشید، کافیست نگاهی به ابزار [GVM](https://github.com/moovweb/gvm) داشته باشید، که یکی از بهترین ابزارهای موجود برای این منظور می باشد. در غیر این صورت همیشه می توانید این کار را به صورت دستی هم انجام دهید. + +## نصب از طریق کد منبع + +برای کامپایل Go 1.5 به بالا، کافیست فقط یکی از ورژن های قبلی Go را بر روی سیستم خود داشته باشید، چرا که Go از ویژگی بوت استرپ پشتیبانی می کند. یعنی برای کامپایل Go، به خود Go احتیاج دارید. + +برای کامپایل Go 1.4 به پایین، شما به یک کامپایلر C بر روی سیستم خود احتیاج دارید. چراکه هنوز بخش هایی از Go به زبان C و همچنین اسمبلر AT&T نوشته شده است. + +اگر از سیستم عامل مک استفاده می کنید و Xcode بر روی سیستم شما نصب است، شما کامپایلر مورد نیاز خود را دارید. + +بر روی سیستم های شبه یونیکس، باید gcc یا کامپایلر مشابه نصب باشد. برای مثال، با استفاده از مدیر بسته apt-get (که در اوبونتو استفاده می شود)، کامپایلرهای مورد نیاز خود را به صورت زیر می توانید نصب کنید. + +
+ +```sh +sudo apt-get install gcc libc6-dev +``` + +
+ +اگر از سیستم عامل ویندوز استفاده می کنید، برای نصب gcc ابتدا باید MinGW را نصب کنید. همچنین به خاطر بسپارید که بعد از اتمام مراحل نصب، محیط متغیرها را تنظیم کنید.( ***اگر از نسخه ۶۴ بیتی ویندوز استفاده می کنید، ورژن ۶۴ بیتی MinGW را نصب کنید.*** ) + +در این مرحله، دستورات زیر را اجرا کنید تا از کد منبع Go یک کلون گرفته و آن را کامپایل نمایید.( ***با این دستور، سورس کد مورد نیاز در دایرکتوری جاری شما کلون می شود. قبل از اینکه ادامه دهید، مسیر کاری خود را تغییر دهید. این امر ممکن است کمی زمان ببرد.*** ) + +
+ + git clone https://go.googlesource.com/go + cd go/src + ./all.bash + +
+ +اگر مراحل نصب با موفقیت انجام شده باشد، با پیغام "ALL TESTS PASSED." مواجه خواهید شد که به معنای موفق بودن تست ها می باشد. + + +بر روی ویندوز، همین کار را می توان با اجرای `all.bat` انجام داد. + + +اگر از ویندوز استفاده می کنید، پکیج های نصب به صورت خودکار تنظیمات لازم در محیط متغیرهای شما را اعمال می کنند. در سیستم های شبه یونیکس، احتیاج است که این متغیرها به صورت دستی تنظیم شوند که در ادامه نحوه تنظیم آن ها را مشاهده خواهید کرد. ( ***اگر ورژن Go شما بیشتر از ۱.۰ باشد، احتیاجی به تنظیم متغیر $GOBIN نمی باشد، و در واقع این متغیر به صورت خودکار به مسیر $GOROOT/bin مرتبط می شود. در فصل بعد بیشتر به این موضوع می پردازیم.*** ) + +
+ + export GOROOT=$HOME/go + export GOBIN=$GOROOT/bin + export PATH=$PATH:$GOROOT/bin + +
+ +اگر بر روی صفحه نمایش خود، پیغام زیر را مشاهده می کنید، یعنی همه چیز به درستی تنظیم شده است. + +![](images/1.1.mac.png?raw=true) + +شکل ۱.۱ اطلاعات سیستم بعد از کامپایل سورس کد + +اگر این اطلاعات را درباره Go مشاهده کردید، بدین معناست که شما موفق شده اید Go را به درستی بر روی کامپیوتر خود نصب کنید. اگر پیغام "no such command" یا به عبارتی "چنین دستوری وجود ندارد" را دریافت کردید، متغیر $PATH خود را بررسی کنید و مطمئن شوید که مسیر نصبی Go را در بر دارد. + +## استفاده از بسته های نصبی استاندارد + +Go برای همه سیستم عامل هایی که از آن پشتیبانی می کنند، بسته هایی ارائه داده است که صرفا با یک کلیک نصب می شوند. این بسته ها به صورت پیش فرص در مسیر `/usr/local/go` (در ویندوز `c:\Go`) نصب می شوند. قطعا این مسیرها قابل تغییر است، اما توجه کنید که با تغییر مسیر، تغییرات لازم را در متغیرهای محیطی نیز به صورت دستی اعمال کنید. + +### چگونه مطمئن شوید که سیستم عامل شما ۳۲ بیتی است یا ۶۴ بیتی؟ + +گام بعدی ما بسیار وابسته به نوع سیستم عامل شما دارد، بنابراین قبل از اینکه بسته های نصبی استاندارد را دانلود کنیم، باید آن را بررسی نماییم. + +اگر از ویندوز استفاده می کنید، کلیدهای `Win+R` را فشار داده و ابزار دستوری را اجرا کنید. دستور `systeminfo` را تایپ کنید تا به شما اطلاعات لازم را درباره سیستم نمایش دهد. سپس خطی را پیدا کنید که در آن اطلاعات مربوط به نوع سیستم یا "system type" نمایش داده شده است. اگر عبارت "x64-based PC" را مشاهده کردید یعنی سیستم عامل شما ۶۴ بیتی، و در غیر این صورت ۳۲ بیتی می باشد. + +اگر کاربر مک هستید، به شما پیشنهاد می کنیم که از بسته ۶۴ بیتی استفاده کنید، چراکه Go پشتیبانی از پردازنده های ۳۲ بیتی بر روی مک را متوقف کرده است. + +کاربران لینوکس کافیست دستور `uname -a` را در ترمینال وارد کرده و اطلاعات مربوط به سیستم خود را مشاهده کنند. یک سیستم عامل ۶۴ بیتی اطلاعاتی مشابه با متن زیر خواهد داشت: + +
+ + <توضیحات> x86_64 x86_64 x86_64 GNU/Linux + // برخی سیستم ها مثلا اوبونتو ۱۰.۰۴ خروجی مشابه زیر خواهد داشت + x86_64 GNU/Linux + +
+ +این اطلاعات برای سیستم عامل های ۳۲ بیتی مشابه زیر خواهد بود: + +
+ + <توضیحات> i686 i686 i386 GNU/Linux + +
+ +### مک + +به [صفحه دانلود](https://golang.org/dl/) رفته، بسته `go1.4.2.darwin-386.pkg` را برای سیستم عامل ۳۲ بیتی (آخرین نسخه، بسته ای برای پردازنده ۳۲ بیتی ندارد) و بسته `go1.8.3.darwin-amd64.pkg` را برای سیستم های ۶۴ بیتی انتخاب کنید. سپس مراحل نصب را صرفا با زدن "next" تا انتها دنبال کنید. بعد از اینکه مراحل نصب با موفقیت به پایان رسید، دایرکتوری `~/go/bin` به متغیر $PATH سیستم شما افزوده خواهد شد. حال کافیست یک ترمینال باز کرده و عبارت `go` را وارد کنید. خروجی حاصل از اجرای این دستور، چیزی مشابه با شکل ۱.۱ خواهد بود. + +### لینوکس + +به [صفحه دانلود](https://golang.org/dl/) رفته، بسته `go1.8.3.linux-386.tar.gz` را برای سیستم های ۳۲ بیتی و بسته `go1.8.3.linux-amd64.tar.gz` را برای سیستم های ۶۴ بیتی انتخاب و دانلود کنید. با فرض اینکه دایرکتوری مورد نظر شما برای نصب Go، مسیر `$GO_INSTALL_DIR` باشد، بسته دانلودی خود را در این مسیر با استفاده از دستور `tar zxvf go1.8.3.linux-amd64.tar.gz -C $GO_INSTALL_DIR`، از حالت فشرده خارج کنید. سپس $PATH خود را با استفاده از دستور `export PATH=$PATH:$GO_INSTALL_DIR/go/bin` تنظیم کنید. حال کافیست ترمینال خود را باز کرده و عبارت `go` را تایپ کنید. خروجی شما چیزی مشابه با شکل ۱.۱ خواهد بود. + +### ویندوز + +به [صفحه دانلود](https://golang.org/dl/) رفته، بسته `go1.8.3.windows-386.msi` را برای سیستم های ۳۲ بیتی و `go1.8.3.windows-amd64.msi` را برای سیستم های ۶۴ بیتی انتخاب و دانلود کنید. مراحل نصب را صرفا با کلیک بر روی "next" تا انتها ادامه دهید. بعد از اینکه نصب با موفقیت انجام شد، `c:/go/bin` به `path` افزوده می شود. حال کافیست یک پنجره دستور خطی باز کرده و عبارت `go` را تایپ کنید. خروجی شما چیزی مشابه با شکل ۱.۱ خواهد بود. + +## استفاده از ابزارهای سوم شخص (third-party) + +### GVM + +GVM یک ابزار کنترل ورژن برای Go محسوب می شود که با استفاده از ابزارهای سوم شخص توسعه یافته است (مثل rvm برای ruby). استفاده از این ابزار بسیار آسان است. کافیست با استفاده از دستور زیر در ترمینال، ابتدا gvm را نصب کنید: + +
+ + bash < <(curl -s -S -L https://raw.github.com/moovweb/gvm/master/binscripts/gvm-installer) + +
+ +سپس با اجرای دستورات زیر، Go را نصب کنید: + +
+ + gvm install go1.8.3 + gvm use go1.8.3 + +
+ +بعد از اینکه فرآیند نصب کامل شد، همه چیز برای استفاده آماده و مهیاست. + +### apt-get + +اوبونتو یکی از مشهورترین توزیع های لینوکسی محسوب می شود که برای دسکتاپ و سرور ارائه شده است. در این توزیع، از ابزار `apt-get` برای مدیریت بسته ها استفاده می شود، بنابراین با استفاده از دستورات زیر به راحتی می توان Go را بر روی اوبونتو نصب نمود. + +
+ + sudo add-apt-repository ppa:gophers/go + sudo apt-get update + sudo apt-get install golang-go + +
+ +### wget + +
+ +```sh + +wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz +sudo tar -xzf go1.8.3.linux-amd64.tar.gz -C /usr/local + +# Go environment +export GOROOT=/usr/local/go +export GOBIN=$GOROOT/bin +export PATH=$PATH:$GOBIN +export GOPATH=$HOME/gopath +``` + +
+ +از ورژن ۱.۸ به بعد، برای متغیر محیطی GOPATH یک مقدار پیش فرض در نظر گرفته شده است. اگر از سیستم های شبه یونیکس استفاده می کنید این متغیر مقدار `$HOME/go` و اگر کاربر ویندوز هستید مقدار `%USERPROFILE%/go` را در بر خواهد داشت. + +### Homebrew + +Homebrew ابزاری برای مدیریت نرم افزار می باشد که در مک به شکل رایج جهت مدیریت بسته ها مورد استفاده قرار می گیرد. برای نصب Go کافیست دستورات زیر را وارد کنید. + +1. نصب Homebrew + +
+ +```sh + /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" +``` + +
+ +2. نصب Go + +
+ +```sh + brew update && brew upgrade + brew install go +``` +
+ +## لینک‌ها + +- [فهرست مطالب](preface.md) +- بخش قبلی: [پیکربندی محیط Go](01.0.md) +- بخش بعدی: [$GOPATH و فضای کاری](01.2.md) + +
\ No newline at end of file diff --git a/fa/README.md b/fa/README.md new file mode 100644 index 00000000..d47805a2 --- /dev/null +++ b/fa/README.md @@ -0,0 +1,57 @@ +
+ +***ساخت وب اپلیکیشن با استفاده از Golang*** +====================================== + +### اهداف + +از آن جایی که من به توسعه اپلیکیشن در زمینه وب علاقمندم، این کتاب را در وقت آزادم به عنوان یک نسخه متن باز و رایگان تدارک دیدم. این امر الزاما به این معنا نیست که من در ساخت اپلیکیشن های وب مهارت خیلی خوبی دارم. صرفا علاقه داشتم که تجربیات خودم را در ساخت اپلیکیشن وب با استفاده از Go به اشتراک بگذارم. + +- اگر در حال حاضر برای ساخت اپلیکیشن وب از زبان هایی مانند PHP/Python/Ruby استفاده می کنید، در این کتاب شما نحوه استفاده از زبان Go را خواهید آموخت. +- اگر شما برنامه نویسی هستید که با زبان هایی مثل C/C++ کار می کنید، در این کتاب نحوه ی عملکرد وب را فرا خواهید گرفت. + +اعتقاد من بر این است که هدف از مطالعه، اشتراک اطلاعات با دیگران است. در زندگی شخصی هر چقدر چیزی را با افراد بیشتری به اشتراک بگذارم، باعث خرسندی بیشتر من خواهد بود. + +# دونیت + +
+ +AliPay: alipay + +English Donate:[donate](http://beego.me/donate) + +
+ +## جامعه + +
+ +QQ群:386056972 + +BBS:[http://gocn.io/](http://gocn.io/) + +
+ +### تقدیر و تشکر + +
+ + - [四月份平民 April Citizen](https://plus.google.com/110445767383269817959) (review code) + - [洪瑞琦 Hong Ruiqi](https://github.com/hongruiqi) (review code) + - [边 疆 BianJiang](https://github.com/border) (write the configurations about Vim and Emacs for Go development) + - [欧林猫 Oling Cat](https://github.com/OlingCat)(review code) + - [吴文磊 Wenlei Wu](mailto:spadesacn@gmail.com)(provide some pictures) + - [北极星 Polaris](https://github.com/polaris1119)(review whole book) + - [雨 痕 Rain Trail](https://github.com/qyuhen)(review chapter 2 and 3) + +
+ +### مجوز + +لازم است بدانید که این کتاب تحت مجوز [CC BY-SA 3.0 License](http://creativecommons.org/licenses/by-sa/3.0/) قرار دارد، +و همچنین کدهای استفاده شده در این کتاب تحت مجوز [BSD 3-Clause License]() می باشند، مگر در مواردی که مجوز آن ذکر شده است. + +### شروع کنید + +[فهرست مطالب](./preface.md) +
\ No newline at end of file diff --git a/fa/code/readme.md b/fa/code/readme.md new file mode 100644 index 00000000..f6d4510d --- /dev/null +++ b/fa/code/readme.md @@ -0,0 +1,7 @@ +## Workspace setup. + +To avoid workspace issues and be able to develop from any folder within this path, +set the environment variable `GOPATH` to the path of this directory. + +More info: +- [GOPATH documentation](http://golang.org/doc/code.html#GOPATH) diff --git a/fa/code/src/apps/ch.1.2/main.go b/fa/code/src/apps/ch.1.2/main.go new file mode 100644 index 00000000..cc5b4e22 --- /dev/null +++ b/fa/code/src/apps/ch.1.2/main.go @@ -0,0 +1,14 @@ +// Example code for Chapter 1.2 from "Build Web Application with Golang" +// Purpose: Run this file to check if your workspace is setup correctly. +// To run, navigate to the current directory in a console and type `go run main.go` +// If the text "Hello World" isn't shown, then setup your workspace again. +package main + +import ( + "fmt" + "mymath" +) + +func main() { + fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) +} diff --git a/fa/code/src/apps/ch.2.1/main.go b/fa/code/src/apps/ch.2.1/main.go new file mode 100644 index 00000000..1aa5bae1 --- /dev/null +++ b/fa/code/src/apps/ch.2.1/main.go @@ -0,0 +1,11 @@ +// Example code for Chapter ? from "Build Web Application with Golang" +// Purpose: Hello world example demonstrating UTF-8 support. +// To run in the console, type `go run main.go` +// You're missing language fonts, if you're seeing squares or question marks. +package main + +import "fmt" + +func main() { + fmt.Printf("Hello, world or 你好,世界 or καλημ ́ρα κóσμ or こんにちは世界\n") +} diff --git a/fa/code/src/apps/ch.2.2/main.go b/fa/code/src/apps/ch.2.2/main.go new file mode 100644 index 00000000..5b54b9c5 --- /dev/null +++ b/fa/code/src/apps/ch.2.2/main.go @@ -0,0 +1,277 @@ +// Example code for Chapter 2.2 from "Build Web Application with Golang" +// Purpose: Goes over the assignment and manipulation of basic data types. +package main + +import ( + "errors" + "fmt" +) + +// constants +const Pi = 3.1415926 + +// booleans default to `false` +var isActive bool // global variable +var enabled, disabled = true, false // omit type of variables + +// grouped definitions +const ( + i = 1e4 + MaxThread = 10 + prefix = "astaxie_" +) + +var ( + frenchHello string // basic form to define string + emptyString string = "" // define a string with empty string +) + +func show_multiple_assignments() { + fmt.Println("show_multiple_assignments()") + var v1 int = 42 + + // Define three variables with type "int", and initialize their values. + // vname1 is v1, vname2 is v2, vname3 is v3 + var v2, v3 int = 2, 3 + + // `:=` only works in functions + // `:=` is the short way of declaring variables without + // specifying the type and using the keyboard `var`. + vname1, vname2, vname3 := v1, v2, v3 + + // `_` disregards the returned value. + _, b := 34, 35 + + fmt.Printf("vname1 = %v, vname2 = %v, vname3 = %v\n", vname1, vname2, vname3) + fmt.Printf("v1 = %v, v2 = %v, v3 = %v\n", v1, v2, v3) + fmt.Println("b =", b) +} +func show_bool() { + fmt.Println("show_bool()") + var available bool // local variable + valid := false // Shorthand assignment + available = true // assign value to variable + + fmt.Printf("valid = %v, !valid = %v\n", valid, !valid) + fmt.Printf("available = %v\n", available) +} +func show_different_types() { + fmt.Println("show_different_types()") + var ( + unicodeChar rune + a int8 + b int16 + c int32 + d int64 + e byte + f uint8 + g int16 + h uint32 + i uint64 + ) + var cmplx complex64 = 5 + 5i + + fmt.Println("Default values for int types") + fmt.Println(unicodeChar, a, b, c, d, e, f, g, h, i) + + fmt.Printf("Value is: %v\n", cmplx) +} +func show_strings() { + fmt.Println("show_strings()") + no, yes, maybe := "no", "yes", "maybe" // brief statement + japaneseHello := "Ohaiyou" + frenchHello = "Bonjour" // basic form of assign values + + fmt.Println("Random strings") + fmt.Println(frenchHello, japaneseHello, no, yes, maybe) + + // The backtick, `, will not escape any character in a string + fmt.Println(`This + is on + multiple lines`) +} +func show_string_manipulation() { + fmt.Println("show_string_manipulation()") + var s string = "hello" + + //You can't do this with strings + //s[0] = 'c' + + s = "hello" + c := []byte(s) // convert string to []byte type + c[0] = 'c' + s2 := string(c) // convert back to string type + + m := " world" + a := s + m + + d := "c" + s[1:] // you cannot change string values by index, but you can get values instead. + fmt.Printf("%s\n", d) + + fmt.Printf("s = %s, c = %v\n", s, c) + fmt.Printf("s2 = %s\n", s2) + fmt.Printf("combined strings\na = %s, d = %s\n", a, d) +} +func show_errors() { + fmt.Println("show_errors()") + err := errors.New("Example error message\n") + if err != nil { + fmt.Print(err) + } +} +func show_iota() { + fmt.Println("show_iota()") + const ( + x = iota // x == 0 + y = iota // y == 1 + z = iota // z == 2 + w // If there is no expression after constants name, + // it uses the last expression, so here is saying w = iota implicitly. + // Therefore w == 3, and y and x both can omit "= iota" as well. + ) + + const v = iota // once iota meets keyword `const`, it resets to `0`, so v = 0. + + const ( + e, f, g = iota, iota, iota // e=0,f=0,g=0 values of iota are same in one line. + ) + fmt.Printf("x = %v, y = %v, z = %v, w = %v\n", x, y, z, w) + fmt.Printf("v = %v\n", v) + fmt.Printf("e = %v, f = %v, g = %v\n", e, f, g) +} + +// Functions and variables starting with a capital letter are public to other packages. +// Everything else is private. +func This_is_public() {} +func this_is_private() {} + +func set_default_values() { + // default values for the types. + const ( + a int = 0 + b int8 = 0 + c int32 = 0 + d int64 = 0 + e uint = 0x0 + f rune = 0 // the actual type of rune is int32 + g byte = 0x0 // the actual type of byte is uint8 + h float32 = 0 // length is 4 byte + i float64 = 0 //length is 8 byte + j bool = false + k string = "" + ) +} +func show_arrays() { + fmt.Println("show_arrays()") + var arr [10]int // an array of type int + arr[0] = 42 // array is 0-based + arr[1] = 13 // assign value to element + + a := [3]int{1, 2, 3} // define a int array with 3 elements + + b := [10]int{1, 2, 3} + // define a int array with 10 elements, + // and first three are assigned, rest of them use default value 0. + + c := [...]int{4, 5, 6} // use `…` replace with number of length, Go will calculate it for you. + + // define a two-dimensional array with 2 elements, and each element has 4 elements. + doubleArray := [2][4]int{[4]int{1, 2, 3, 4}, [4]int{5, 6, 7, 8}} + + // You can write about declaration in a shorter way. + easyArray := [2][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}} + + fmt.Println("arr =", arr) + fmt.Printf("The first element is %d\n", arr[0]) // get element value, it returns 42 + fmt.Printf("The last element is %d\n", arr[9]) + //it returns default value of 10th element in this array, which is 0 in this case. + + fmt.Println("array a =", a) + fmt.Println("array b =", b) + fmt.Println("array c =", c) + + fmt.Println("array doubleArray =", doubleArray) + fmt.Println("array easyArray =", easyArray) +} +func show_slices() { + fmt.Println("show_slices()") + // define a slice with 10 elements which types are byte + var ar = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} + + // define two slices with type []byte + var a, b []byte + + // a points to elements from 3rd to 5th in array ar. + a = ar[2:5] + // now a has elements ar[2]、ar[3] and ar[4] + + // b is another slice of array ar + b = ar[3:5] + // now b has elements ar[3] and ar[4] + + // define an array + var array = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} + // define two slices + var aSlice, bSlice []byte + + // some convenient operations + aSlice = array[:3] // equals to aSlice = array[0:3] aSlice has elements a,b,c + aSlice = array[5:] // equals to aSlice = array[5:10] aSlice has elements f,g,h,i,j + aSlice = array[:] // equals to aSlice = array[0:10] aSlice has all elements + + // slice from slice + aSlice = array[3:7] // aSlice has elements d,e,f,g,len=4,cap=7 + bSlice = aSlice[1:3] // bSlice contains aSlice[1], aSlice[2], so it has elements e,f + bSlice = aSlice[:3] // bSlice contains aSlice[0], aSlice[1], aSlice[2], so it has d,e,f + bSlice = aSlice[0:5] // slcie could be expanded in range of cap, now bSlice contains d,e,f,g,h + bSlice = aSlice[:] // bSlice has same elements as aSlice does, which are d,e,f,g + + fmt.Println("slice ar =", ar) + fmt.Println("slice a =", a) + fmt.Println("slice b =", b) + fmt.Println("array =", array) + fmt.Println("slice aSlice =", aSlice) + fmt.Println("slice bSlice =", bSlice) + fmt.Println("len(bSlice) =", len(bSlice)) +} +func show_map() { + fmt.Println("show_map()") + // use string as key type, int as value type, and you have to use `make` initialize it. + var numbers map[string]int + // another way to define map + numbers = make(map[string]int) + numbers["one"] = 1 // assign value by key + numbers["ten"] = 10 + numbers["three"] = 3 + + // Initialize a map + rating := map[string]float32{"C": 5, "Go": 4.5, "Python": 4.5, "C++": 2} + + fmt.Println("map numbers =", numbers) + fmt.Println("The third number is: ", numbers["three"]) // get values + // It prints: The third number is: 3 + + // map has two return values. For second value, if the key doesn't exist,ok is false,true otherwise. + csharpRating, ok := rating["C#"] + if ok { + fmt.Println("C# is in the map and its rating is ", csharpRating) + } else { + fmt.Println("We have no rating associated with C# in the map") + } + + delete(rating, "C") // delete element with key "c" + fmt.Printf("map rating = %#v\n", rating) +} +func main() { + show_multiple_assignments() + show_bool() + show_different_types() + show_strings() + show_string_manipulation() + show_errors() + show_iota() + set_default_values() + show_arrays() + show_slices() + show_map() +} diff --git a/fa/code/src/apps/ch.2.2/what_is_wrong_with_this/main.go b/fa/code/src/apps/ch.2.2/what_is_wrong_with_this/main.go new file mode 100644 index 00000000..b435f038 --- /dev/null +++ b/fa/code/src/apps/ch.2.2/what_is_wrong_with_this/main.go @@ -0,0 +1,8 @@ +// Example code for Chapter 2.2 from "Build Web Application with Golang" +// Purpose: Try to fix this program. +// From the console, type `go run main.go` +package main + +func main() { + var i int +} diff --git a/fa/code/src/apps/ch.2.3/basic_functions/main.go b/fa/code/src/apps/ch.2.3/basic_functions/main.go new file mode 100644 index 00000000..6f6a63f4 --- /dev/null +++ b/fa/code/src/apps/ch.2.3/basic_functions/main.go @@ -0,0 +1,26 @@ +// Example code for Chapter 2.3 from "Build Web Application with Golang" +// Purpose: Creating a basic function +package main + +import "fmt" + +// return greater value between a and b +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func main() { + x := 3 + y := 4 + z := 5 + + max_xy := max(x, y) // call function max(x, y) + max_xz := max(x, z) // call function max(x, z) + + fmt.Printf("max(%d, %d) = %d\n", x, y, max_xy) + fmt.Printf("max(%d, %d) = %d\n", x, z, max_xz) + fmt.Printf("max(%d, %d) = %d\n", y, z, max(y, z)) // call function here +} diff --git a/fa/code/src/apps/ch.2.3/hidden_print_methods/main.go b/fa/code/src/apps/ch.2.3/hidden_print_methods/main.go new file mode 100644 index 00000000..0d3df05a --- /dev/null +++ b/fa/code/src/apps/ch.2.3/hidden_print_methods/main.go @@ -0,0 +1,14 @@ +// As of Google go 1.1.2, `println()` and `print()` are hidden functions included from the runtime package. +// However it's encouraged to use the print functions from the `fmt` package. +package main + +import "fmt" + +func f() { + fmt.Println("First") + print("Second ") + println(" Third") +} +func main() { + f() +} diff --git a/fa/code/src/apps/ch.2.3/import_packages/main.go b/fa/code/src/apps/ch.2.3/import_packages/main.go new file mode 100644 index 00000000..c4d72756 --- /dev/null +++ b/fa/code/src/apps/ch.2.3/import_packages/main.go @@ -0,0 +1,26 @@ +// Example code for Chapter 2.3 from "Build Web Application with Golang" +// Purpose: Shows different ways of importing a package. +// Note: For the package `only_call_init`, we reference the path from the +// base directory of `$GOPATH/src`. The reason being Golang discourage +// the use of relative paths when import packages. +// BAD: "./only_call_init" +// GOOD: "apps/ch.2.3/import_packages/only_call_init" +package main + +import ( + // `_` will only call init() inside the package only_call_init + _ "apps/ch.2.3/import_packages/only_call_init" + f "fmt" // import the package as `f` + . "math" // makes the public methods and constants global + "mymath" // custom package located at $GOPATH/src/ + "os" // normal import of a standard package + "text/template" // the package takes the name of last folder path, `template` +) + +func main() { + f.Println("mymath.Sqrt(4) =", mymath.Sqrt(4)) + f.Println("E =", E) // references math.E + + t, _ := template.New("test").Parse("Pi^2 = {{.}}") + t.Execute(os.Stdout, Pow(Pi, 2)) +} diff --git a/fa/code/src/apps/ch.2.3/import_packages/only_call_init/only_call_init.go b/fa/code/src/apps/ch.2.3/import_packages/only_call_init/only_call_init.go new file mode 100644 index 00000000..789a6c79 --- /dev/null +++ b/fa/code/src/apps/ch.2.3/import_packages/only_call_init/only_call_init.go @@ -0,0 +1,7 @@ +package only_call_init + +import "fmt" + +func init() { + fmt.Println("only_call_init.init() was called.") +} diff --git a/fa/code/src/apps/ch.2.3/main.go b/fa/code/src/apps/ch.2.3/main.go new file mode 100644 index 00000000..0b3ea566 --- /dev/null +++ b/fa/code/src/apps/ch.2.3/main.go @@ -0,0 +1,142 @@ +// Example code for Chapter 2.3 from "Build Web Application with Golang" +// Purpose: Goes over if, else, switch conditions, loops and defer. +package main + +import "fmt" + +func computedValue() int { + return 1 +} +func show_if() { + fmt.Println("\n#show_if()") + x := computedValue() + integer := 23 + + fmt.Println("x =", x) + fmt.Println("integer =", integer) + if x > 10 { + fmt.Println("x is greater than 10") + } else { + fmt.Println("x is less than 10") + } + + if integer == 3 { + fmt.Println("The integer is equal to 3") + } else if integer < 3 { + fmt.Println("The integer is less than 3") + } else { + fmt.Println("The integer is greater than 3") + } +} +func show_if_var() { + fmt.Println("\n#show_if_var()") + // initialize x, then check if x greater than + if x := computedValue(); x > 10 { + fmt.Println("x is greater than 10") + } else { + fmt.Println("x is less than 10") + } + + // the following code will not compile, since `x` is only accessible with the if/else block + // fmt.Println(x) +} +func show_goto() { + fmt.Println("\n#show_goto()") + // The call to the label switches the goroutine it seems. + i := 0 +Here: // label ends with ":" + fmt.Println(i) + i++ + if i < 10 { + goto Here // jump to label "Here" + } +} +func show_for_loop() { + fmt.Println("\n#show_for_loop()") + sum := 0 + for index := 0; index < 10; index++ { + sum += index + } + fmt.Println("part 1, sum is equal to ", sum) + + sum = 1 + // The compiler will remove the `;` from the line below. + // for ; sum < 1000 ; { + for sum < 1000 { + sum += sum + } + fmt.Println("part 2, sum is equal to ", sum) + + for index := 10; 0 < index; index-- { + if index == 5 { + break // or continue + } + fmt.Println(index) + } + +} +func show_loop_through_map() { + fmt.Println("\n#show_loop_through_map()") + m := map[string]int{ + "one": 1, + "two": 2, + "three": 3, + } + fmt.Println("map value = ", m) + for k, v := range m { + fmt.Println("map's key: ", k) + fmt.Println("map's value: ", v) + } +} +func show_switch() { + fmt.Println("\n#show_switch()") + i := 10 + switch i { + case 1: + fmt.Println("i is equal to 1") + case 2, 3, 4: + fmt.Println("i is equal to 2, 3 or 4") + case 10: + fmt.Println("i is equal to 10") + default: + fmt.Println("All I know is that i is an integer") + } + + integer := 6 + fmt.Println("integer =", integer) + switch integer { + case 4: + fmt.Println("integer == 4") + fallthrough + case 5: + fmt.Println("integer <= 5") + fallthrough + case 6: + fmt.Println("integer <= 6") + fallthrough + case 7: + fmt.Println("integer <= 7") + fallthrough + case 8: + fmt.Println("integer <= 8") + fallthrough + default: + fmt.Println("default case") + } +} +func show_defer() { + fmt.Println("\nshow_defer()") + defer fmt.Println("(last defer)") + for i := 0; i < 5; i++ { + defer fmt.Printf("%d ", i) + } +} +func main() { + show_if() + show_if_var() + show_goto() + show_for_loop() + show_loop_through_map() + show_switch() + show_defer() +} diff --git a/fa/code/src/apps/ch.2.3/panic_and_recover/main.go b/fa/code/src/apps/ch.2.3/panic_and_recover/main.go new file mode 100644 index 00000000..88398668 --- /dev/null +++ b/fa/code/src/apps/ch.2.3/panic_and_recover/main.go @@ -0,0 +1,31 @@ +// Example code for Chapter 2.3 from "Build Web Application with Golang" +// Purpose: Showing how to use `panic()` and `recover()` +package main + +import ( + "fmt" + "os" +) + +var user = os.Getenv("USER") + +func check_user() { + if user == "" { + panic("no value for $USER") + } + fmt.Println("Environment Variable `USER` =", user) +} +func throwsPanic(f func()) (b bool) { + defer func() { + if x := recover(); x != nil { + fmt.Println("Panic message =", x); + b = true + } + }() + f() // if f causes panic, it will recover + return +} +func main(){ + didPanic := throwsPanic(check_user) + fmt.Println("didPanic =", didPanic) +} diff --git a/fa/code/src/apps/ch.2.3/pass_by_value_and_pointer/main.go b/fa/code/src/apps/ch.2.3/pass_by_value_and_pointer/main.go new file mode 100644 index 00000000..1c9e9c75 --- /dev/null +++ b/fa/code/src/apps/ch.2.3/pass_by_value_and_pointer/main.go @@ -0,0 +1,31 @@ +// Example code for Chapter 2.3 from "Build Web Application with Golang" +// Purpose: Shows passing a variable by value and reference +package main + +import "fmt" + +func add_by_value(a int) int { + a = a + 1 + return a +} +func add_by_reference(a *int) int { + *a = *a + 1 + return *a +} +func show_add_by_value() { + x := 3 + fmt.Println("x = ", x) + fmt.Println("add_by_value(x) =", add_by_value(x) ) + fmt.Println("x = ", x) +} +func show_add_by_reference() { + x := 3 + fmt.Println("x = ", x) + // &x pass memory address of x + fmt.Println("add_by_reference(&x) =", add_by_reference(&x) ) + fmt.Println("x = ", x) +} +func main() { + show_add_by_value() + show_add_by_reference() +} diff --git a/fa/code/src/apps/ch.2.3/type_function/main.go b/fa/code/src/apps/ch.2.3/type_function/main.go new file mode 100644 index 00000000..6645d4fe --- /dev/null +++ b/fa/code/src/apps/ch.2.3/type_function/main.go @@ -0,0 +1,44 @@ +// Example code for Chapter 2.3 from "Build Web Application with Golang" +// Purpose: Shows how to define a function type +package main + +import "fmt" + +type testInt func(int) bool // define a function type of variable + +func isOdd(integer int) bool { + if integer%2 == 0 { + return false + } + return true +} + +func isEven(integer int) bool { + if integer%2 == 0 { + return true + } + return false +} + +// pass the function `f` as an argument to another function + +func filter(slice []int, f testInt) []int { + var result []int + for _, value := range slice { + if f(value) { + result = append(result, value) + } + } + return result +} +func init() { + fmt.Println("\n#init() was called.") +} +func main() { + slice := []int{1, 2, 3, 4, 5, 7} + fmt.Println("slice = ", slice) + odd := filter(slice, isOdd) // use function as values + fmt.Println("Odd elements of slice are: ", odd) + even := filter(slice, isEven) + fmt.Println("Even elements of slice are: ", even) +} diff --git a/fa/code/src/apps/ch.2.3/variadic_functions/main.go b/fa/code/src/apps/ch.2.3/variadic_functions/main.go new file mode 100644 index 00000000..559222fe --- /dev/null +++ b/fa/code/src/apps/ch.2.3/variadic_functions/main.go @@ -0,0 +1,20 @@ +// Example code for Chapter 2.3 from "Build Web Application with Golang" +// Purpose: Shows how to return multiple values from a function +package main + +import "fmt" + +// return results of A + B and A * B +func SumAndProduct(A, B int) (int, int) { + return A + B, A * B +} + +func main() { + x := 3 + y := 4 + + xPLUSy, xTIMESy := SumAndProduct(x, y) + + fmt.Printf("%d + %d = %d\n", x, y, xPLUSy) + fmt.Printf("%d * %d = %d\n", x, y, xTIMESy) +} diff --git a/fa/code/src/apps/ch.2.4/compare_age/main.go b/fa/code/src/apps/ch.2.4/compare_age/main.go new file mode 100644 index 00000000..76772c56 --- /dev/null +++ b/fa/code/src/apps/ch.2.4/compare_age/main.go @@ -0,0 +1,43 @@ +// Example code for Chapter 2.4 from "Build Web Application with Golang" +// Purpose: Shows you how to pass and use structs. +package main + +import "fmt" + +// define a new type +type person struct { + name string + age int +} + +// compare age of two people, return the older person and differences of age +// struct is passed by value +func Older(p1, p2 person) (person, int) { + if p1.age > p2.age { + return p1, p1.age - p2.age + } + return p2, p2.age - p1.age +} + +func main() { + var tom person + + // initialization + tom.name, tom.age = "Tom", 18 + + // initialize two values by format "field:value" + bob := person{age: 25, name: "Bob"} + + // initialize two values with order + paul := person{"Paul", 43} + + tb_Older, tb_diff := Older(tom, bob) + tp_Older, tp_diff := Older(tom, paul) + bp_Older, bp_diff := Older(bob, paul) + + fmt.Printf("Of %s and %s, %s is older by %d years\n", tom.name, bob.name, tb_Older.name, tb_diff) + + fmt.Printf("Of %s and %s, %s is older by %d years\n", tom.name, paul.name, tp_Older.name, tp_diff) + + fmt.Printf("Of %s and %s, %s is older by %d years\n", bob.name, paul.name, bp_Older.name, bp_diff) +} diff --git a/fa/code/src/apps/ch.2.4/embedded_structs/main.go b/fa/code/src/apps/ch.2.4/embedded_structs/main.go new file mode 100644 index 00000000..342e51a5 --- /dev/null +++ b/fa/code/src/apps/ch.2.4/embedded_structs/main.go @@ -0,0 +1,39 @@ +// Example code for Chapter 2.4 from "Build Web Application with Golang" +// Purpose: Example of embedded fields +package main + +import "fmt" + +type Human struct { + name string + age int + weight int +} + +type Student struct { + Human // anonymous field, it means Student struct includes all fields that Human has. + speciality string +} + +func main() { + // initialize a student + mark := Student{Human{"Mark", 25, 120}, "Computer Science"} + + // access fields + fmt.Println("His name is ", mark.name) + fmt.Println("His age is ", mark.age) + fmt.Println("His weight is ", mark.weight) + fmt.Println("His speciality is ", mark.speciality) + // modify notes + mark.speciality = "AI" + fmt.Println("Mark changed his speciality") + fmt.Println("His speciality is ", mark.speciality) + // modify age + fmt.Println("Mark become old") + mark.age = 46 + fmt.Println("His age is", mark.age) + // modify weight + fmt.Println("Mark is not an athlete any more") + mark.weight += 60 + fmt.Println("His weight is", mark.weight) +} diff --git a/fa/code/src/apps/ch.2.4/embedded_structs2/main.go b/fa/code/src/apps/ch.2.4/embedded_structs2/main.go new file mode 100644 index 00000000..9f8e292d --- /dev/null +++ b/fa/code/src/apps/ch.2.4/embedded_structs2/main.go @@ -0,0 +1,39 @@ +// Example code for Chapter 2.4 from "Build Web Application with Golang" +// Purpose: Another example of embedded fields +package main + +import "fmt" + +type Skills []string + +type Human struct { + name string + age int + weight int +} + +type Student struct { + Human // struct as embedded field + Skills // string slice as embedded field + int // built-in type as embedded field + speciality string +} + +func main() { + // initialize Student Jane + jane := Student{Human: Human{"Jane", 35, 100}, speciality: "Biology"} + // access fields + fmt.Println("Her name is ", jane.name) + fmt.Println("Her age is ", jane.age) + fmt.Println("Her weight is ", jane.weight) + fmt.Println("Her speciality is ", jane.speciality) + // modify value of skill field + jane.Skills = []string{"anatomy"} + fmt.Println("Her skills are ", jane.Skills) + fmt.Println("She acquired two new ones ") + jane.Skills = append(jane.Skills, "physics", "golang") + fmt.Println("Her skills now are ", jane.Skills) + // modify embedded field + jane.int = 3 + fmt.Println("Her preferred number is", jane.int) +} diff --git a/fa/code/src/apps/ch.2.4/embedded_structs_with_name_conflict/main.go b/fa/code/src/apps/ch.2.4/embedded_structs_with_name_conflict/main.go new file mode 100644 index 00000000..61df1683 --- /dev/null +++ b/fa/code/src/apps/ch.2.4/embedded_structs_with_name_conflict/main.go @@ -0,0 +1,24 @@ +// Example code for Chapter 2.4 from "Build Web Application with Golang" +// Purpose: Shows a name conflict with a embedded field +package main + +import "fmt" + +type Human struct { + name string + age int + phone string // Human has phone field +} + +type Employee struct { + Human // embedded field Human + speciality string + phone string // phone in employee +} + +func main() { + Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"} + fmt.Println("Bob's work phone is:", Bob.phone) + // access phone field in Human + fmt.Println("Bob's personal phone is:", Bob.Human.phone) +} diff --git a/fa/code/src/apps/ch.2.4/main.go b/fa/code/src/apps/ch.2.4/main.go new file mode 100644 index 00000000..f6d3a578 --- /dev/null +++ b/fa/code/src/apps/ch.2.4/main.go @@ -0,0 +1,39 @@ +// Example code for Chapter 2.4 from "Build Web Application with Golang" +// Purpose: Shows different ways of creating a struct +package main + +import "fmt" + +func show_basic_struct() { + fmt.Println("\nshow_basic_struct()") + type person struct { + name string + age int + } + + var P person // p is person type + + P.name = "Astaxie" // assign "Astaxie" to the filed 'name' of p + P.age = 25 // assign 25 to field 'age' of p + fmt.Printf("The person's name is %s\n", P.name) // access field 'name' of p + + tom := person{"Tom", 25} + + bob := person{age: 24, name: "Bob"} + + fmt.Printf("tom = %+v\n", tom) + fmt.Printf("bob = %#v\n", bob) +} +func show_anonymous_struct() { + fmt.Println("\nshow_anonymous_struct()") + fmt.Printf("Anonymous struct = %#v\n", struct { + name string + count int + }{ + "counter", 1, + }) +} +func main() { + show_basic_struct() + show_anonymous_struct() +} diff --git a/fa/code/src/apps/ch.2.5/attach_methods_to_struct/main.go b/fa/code/src/apps/ch.2.5/attach_methods_to_struct/main.go new file mode 100644 index 00000000..cc025a61 --- /dev/null +++ b/fa/code/src/apps/ch.2.5/attach_methods_to_struct/main.go @@ -0,0 +1,36 @@ +// Example code from Chapter 2.5 +// Attach method to struct. +package main + +import ( + "fmt" + "math" +) + +type Rectangle struct { + width, height float64 +} + +type Circle struct { + radius float64 +} + +func (r Rectangle) area() float64 { + return r.width * r.height +} + +func (c Circle) area() float64 { + return c.radius * c.radius * math.Pi +} + +func main() { + r1 := Rectangle{12, 2} + r2 := Rectangle{9, 4} + c1 := Circle{10} + c2 := Circle{25} + + fmt.Println("Area of r1 is: ", r1.area()) + fmt.Println("Area of r2 is: ", r2.area()) + fmt.Println("Area of c1 is: ", c1.area()) + fmt.Println("Area of c2 is: ", c2.area()) +} diff --git a/fa/code/src/apps/ch.2.5/box_example/main.go b/fa/code/src/apps/ch.2.5/box_example/main.go new file mode 100644 index 00000000..c0386729 --- /dev/null +++ b/fa/code/src/apps/ch.2.5/box_example/main.go @@ -0,0 +1,73 @@ +package main + +import "fmt" + +const ( + WHITE = iota + BLACK + BLUE + RED + YELLOW +) + +type Color byte + +type Box struct { + width, height, depth float64 + color Color +} + +type BoxList []Box //a slice of boxes + +func (b Box) Volume() float64 { + return b.width * b.height * b.depth +} + +func (b *Box) SetColor(c Color) { + b.color = c +} + +func (bl BoxList) BiggestsColor() Color { + v := 0.00 + k := Color(WHITE) + for _, b := range bl { + if b.Volume() > v { + v = b.Volume() + k = b.color + } + } + return k +} + +func (bl BoxList) PaintItBlack() { + for i, _ := range bl { + bl[i].SetColor(BLACK) + } +} + +func (c Color) String() string { + strings := []string{"WHITE", "BLACK", "BLUE", "RED", "YELLOW"} + return strings[c] +} + +func main() { + boxes := BoxList{ + Box{4, 4, 4, RED}, + Box{10, 10, 1, YELLOW}, + Box{1, 1, 20, BLACK}, + Box{10, 10, 1, BLUE}, + Box{10, 30, 1, WHITE}, + Box{20, 20, 20, YELLOW}, + } + + fmt.Printf("We have %d boxes in our set\n", len(boxes)) + fmt.Println("The volume of the first one is", boxes[0].Volume(), "cm³") + fmt.Println("The color of the last one is", boxes[len(boxes)-1].color.String()) + fmt.Println("The biggest one is", boxes.BiggestsColor().String()) + + fmt.Println("Let's paint them all black") + boxes.PaintItBlack() + fmt.Println("The color of the second one is", boxes[1].color.String()) + + fmt.Println("Obviously, now, the biggest one is", boxes.BiggestsColor().String()) +} diff --git a/fa/code/src/apps/ch.2.5/embedded_method/main.go b/fa/code/src/apps/ch.2.5/embedded_method/main.go new file mode 100644 index 00000000..ed32c73b --- /dev/null +++ b/fa/code/src/apps/ch.2.5/embedded_method/main.go @@ -0,0 +1,31 @@ +package main +import "fmt" + +type Human struct { + name string + age int + phone string +} + +type Student struct { + Human // anonymous field + school string +} + +type Employee struct { + Human + company string +} + +// define a method in Human +func (h *Human) SayHi() { + fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone) +} + +func main() { + mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"} + sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"} + + mark.SayHi() + sam.SayHi() +} diff --git a/fa/code/src/apps/ch.2.5/method_overload/main.go b/fa/code/src/apps/ch.2.5/method_overload/main.go new file mode 100644 index 00000000..c9b2978c --- /dev/null +++ b/fa/code/src/apps/ch.2.5/method_overload/main.go @@ -0,0 +1,36 @@ +package main + +import "fmt" + +type Human struct { + name string + age int + phone string +} + +type Student struct { + Human + school string +} + +type Employee struct { + Human + company string +} + +func (h *Human) SayHi() { + fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone) +} + +func (e *Employee) SayHi() { + fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name, + e.company, e.phone) //Yes you can split into 2 lines here. +} + +func main() { + mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"} + sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"} + + mark.SayHi() + sam.SayHi() +} diff --git a/fa/code/src/apps/ch.2.5/pass_struct_to_method/main.go b/fa/code/src/apps/ch.2.5/pass_struct_to_method/main.go new file mode 100644 index 00000000..4096d4bc --- /dev/null +++ b/fa/code/src/apps/ch.2.5/pass_struct_to_method/main.go @@ -0,0 +1,18 @@ +package main + +import "fmt" + +type Rectangle struct { + width, height float64 +} + +func area(r Rectangle) float64 { + return r.width * r.height +} + +func main() { + r1 := Rectangle{12, 2} + r2 := Rectangle{9, 4} + fmt.Println("Area of r1 is: ", area(r1)) + fmt.Println("Area of r2 is: ", area(r2)) +} diff --git a/fa/code/src/apps/ch.2.6/interface/main.go b/fa/code/src/apps/ch.2.6/interface/main.go new file mode 100644 index 00000000..fc980389 --- /dev/null +++ b/fa/code/src/apps/ch.2.6/interface/main.go @@ -0,0 +1,71 @@ +package main +import "fmt" + +type Human struct { + name string + age int + phone string +} + +type Student struct { + Human + school string + loan float32 +} + +type Employee struct { + Human + company string + money float32 +} + +func (h Human) SayHi() { + fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone) +} + +func (h Human) Sing(lyrics string) { + fmt.Println("La la la la...", lyrics) +} + +func (e Employee) SayHi() { + fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name, + e.company, e.phone) //Yes you can split into 2 lines here. +} + +// Interface Men implemented by Human, Student and Employee +type Men interface { + SayHi() + Sing(lyrics string) +} + +func main() { + mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00} + paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100} + sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000} + Tom := Employee{Human{"Sam", 36, "444-222-XXX"}, "Things Ltd.", 5000} + + // define interface i + var i Men + + //i can store Student + i = mike + fmt.Println("This is Mike, a Student:") + i.SayHi() + i.Sing("November rain") + + //i can store Employee + i = Tom + fmt.Println("This is Tom, an Employee:") + i.SayHi() + i.Sing("Born to be wild") + + // slice of Men + fmt.Println("Let's use a slice of Men and see what happens") + x := make([]Men, 3) + // these three elements are different types but they all implemented interface Men + x[0], x[1], x[2] = paul, sam, mike + + for _, value := range x{ + value.SayHi() + } +} diff --git a/fa/code/src/apps/ch.2.6/reflection/main.go b/fa/code/src/apps/ch.2.6/reflection/main.go new file mode 100644 index 00000000..e0f50f7e --- /dev/null +++ b/fa/code/src/apps/ch.2.6/reflection/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "reflect" +) + +func show_interface_none() { + fmt.Println("\nshow_interface_none()") + var a interface{} + a = "string" + a = 1 + a = false + fmt.Println("a =", a) +} +func show_reflection() { + fmt.Println("\nshow_reflection()") + var x float64 = 3.4 + v := reflect.ValueOf(x) + fmt.Println("type:", v.Type()) + fmt.Println("kind is float64:", v.Kind() == reflect.Float64) + fmt.Println("value:", v.Float()) + + p := reflect.ValueOf(&x) + newX := p.Elem() + newX.SetFloat(7.1) + fmt.Println("newX =", newX) + fmt.Println("newX float64() value:", newX.Float()) +} +func main() { + show_interface_none() + show_reflection() +} diff --git a/fa/code/src/apps/ch.2.6/stringer_interface/main.go b/fa/code/src/apps/ch.2.6/stringer_interface/main.go new file mode 100644 index 00000000..310eb0ee --- /dev/null +++ b/fa/code/src/apps/ch.2.6/stringer_interface/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "strconv" +) + +type Human struct { + name string + age int + phone string +} + +// Human implemented fmt.Stringer +func (h Human) String() string { + return "Name:" + h.name + ", Age:" + strconv.Itoa(h.age) + " years, Contact:" + h.phone +} + +func main() { + Bob := Human{"Bob", 39, "000-7777-XXX"} + fmt.Println("This Human is : ", Bob) +} diff --git a/fa/code/src/apps/ch.2.6/switch_type_check/main.go b/fa/code/src/apps/ch.2.6/switch_type_check/main.go new file mode 100644 index 00000000..9d781675 --- /dev/null +++ b/fa/code/src/apps/ch.2.6/switch_type_check/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "strconv" +) + +type Element interface{} +type List []Element + +type Person struct { + name string + age int +} + +func (p Person) String() string { + return "(name: " + p.name + " - age: " + strconv.Itoa(p.age) + " years)" +} + +func main() { + list := make(List, 3) + list[0] = 1 //an int + list[1] = "Hello" //a string + list[2] = Person{"Dennis", 70} + + for index, element := range list { + switch value := element.(type) { + case int: + fmt.Printf("list[%d] is an int and its value is %d\n", index, value) + case string: + fmt.Printf("list[%d] is a string and its value is %s\n", index, value) + case Person: + fmt.Printf("list[%d] is a Person and its value is %s\n", index, value) + default: + fmt.Println("list[%d] is of a different type", index) + } + } +} diff --git a/fa/code/src/apps/ch.2.6/type_check/main.go b/fa/code/src/apps/ch.2.6/type_check/main.go new file mode 100644 index 00000000..bb051f47 --- /dev/null +++ b/fa/code/src/apps/ch.2.6/type_check/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "fmt" + "strconv" +) + +type Element interface{} +type List []Element + +type Person struct { + name string + age int +} + +func (p Person) String() string { + return "(name: " + p.name + " - age: " + strconv.Itoa(p.age) + " years)" +} + +func main() { + list := make(List, 3) + list[0] = 1 // an int + list[1] = "Hello" // a string + list[2] = Person{"Dennis", 70} + + for index, element := range list { + if value, ok := element.(int); ok { + fmt.Printf("list[%d] is an int and its value is %d\n", index, value) + } else if value, ok := element.(string); ok { + fmt.Printf("list[%d] is a string and its value is %s\n", index, value) + } else if value, ok := element.(Person); ok { + fmt.Printf("list[%d] is a Person and its value is %s\n", index, value) + } else { + fmt.Println("list[%d] is of a different type", index) + } + } +} diff --git a/fa/code/src/apps/ch.2.7/buffered_channel/main.go b/fa/code/src/apps/ch.2.7/buffered_channel/main.go new file mode 100644 index 00000000..f65e06f2 --- /dev/null +++ b/fa/code/src/apps/ch.2.7/buffered_channel/main.go @@ -0,0 +1,13 @@ +// Example code for Chapter 2.7 from "Build Web Application with Golang" +// Purpose: Shows how to use a buffered channel +package main + +import "fmt" + +func main() { + c := make(chan int, 2) // change 2 to 1 will have runtime error, but 3 is fine + c <- 1 + c <- 2 + fmt.Println(<-c) + fmt.Println(<-c) +} diff --git a/fa/code/src/apps/ch.2.7/goroutine/main.go b/fa/code/src/apps/ch.2.7/goroutine/main.go new file mode 100644 index 00000000..bdf1f5c1 --- /dev/null +++ b/fa/code/src/apps/ch.2.7/goroutine/main.go @@ -0,0 +1,20 @@ +// Example code for Chapter 2.7 from "Build Web Application with Golang" +// Purpose: Shows how to launch a simple gorountine +package main + +import ( + "fmt" + "runtime" +) + +func say(s string) { + for i := 0; i < 5; i++ { + runtime.Gosched() + fmt.Println(s) + } +} + +func main() { + go say("world") // create a new goroutine + say("hello") // current goroutine +} diff --git a/fa/code/src/apps/ch.2.7/range_and_close_channel/main.go b/fa/code/src/apps/ch.2.7/range_and_close_channel/main.go new file mode 100644 index 00000000..ce2c4311 --- /dev/null +++ b/fa/code/src/apps/ch.2.7/range_and_close_channel/main.go @@ -0,0 +1,24 @@ +// Example code for Chapter 2.7 from "Build Web Application with Golang" +// Purpose: Shows how to close and interate through a channel +package main + +import ( + "fmt" +) + +func fibonacci(n int, c chan int) { + x, y := 1, 1 + for i := 0; i < n; i++ { + c <- x + x, y = y, x+y + } + close(c) +} + +func main() { + c := make(chan int, 10) + go fibonacci(cap(c), c) + for i := range c { + fmt.Println(i) + } +} diff --git a/fa/code/src/apps/ch.2.7/select_channel/main.go b/fa/code/src/apps/ch.2.7/select_channel/main.go new file mode 100644 index 00000000..50b23781 --- /dev/null +++ b/fa/code/src/apps/ch.2.7/select_channel/main.go @@ -0,0 +1,30 @@ +// Example code for Chapter 2.7 from "Build Web Application with Golang" +// Purpose: Shows how to use `select` +package main + +import "fmt" + +func fibonacci(c, quit chan int) { + x, y := 1, 1 + for { + select { + case c <- x: + x, y = y, x+y + case <-quit: + fmt.Println("quit") + return + } + } +} + +func main() { + c := make(chan int) + quit := make(chan int) + go func() { + for i := 0; i < 10; i++ { + fmt.Println(<-c) + } + quit <- 0 + }() + fibonacci(c, quit) +} diff --git a/fa/code/src/apps/ch.2.7/timeout/main.go b/fa/code/src/apps/ch.2.7/timeout/main.go new file mode 100644 index 00000000..4e937dbb --- /dev/null +++ b/fa/code/src/apps/ch.2.7/timeout/main.go @@ -0,0 +1,27 @@ +// Example code for Chapter 2.7 from "Build Web Application with Golang" +// Purpose: Shows how to create and use a timeout +package main + +import ( + "fmt" + "time" +) + + +func main() { + c := make(chan int) + o := make(chan bool) + go func() { + for { + select { + case v := <-c: + fmt.Println(v) + case <-time.After(5 * time.Second): + fmt.Println("timeout") + o <- true + break + } + } + }() + <-o +} diff --git a/fa/code/src/apps/ch.2.7/unbuffered_channel/main.go b/fa/code/src/apps/ch.2.7/unbuffered_channel/main.go new file mode 100644 index 00000000..455fd4ba --- /dev/null +++ b/fa/code/src/apps/ch.2.7/unbuffered_channel/main.go @@ -0,0 +1,24 @@ +// Example code for Chapter 2.7 from "Build Web Application with Golang" +// Purpose: Shows how to create and use a unbuffered channel +package main + +import "fmt" + +func sum(a []int, c chan int) { + total := 0 + for _, v := range a { + total += v + } + c <- total // send total to c +} + +func main() { + a := []int{7, 2, 8, -9, 4, 0} + + c := make(chan int) + go sum(a[:len(a)/2], c) + go sum(a[len(a)/2:], c) + x, y := <-c, <-c // receive from c + + fmt.Println(x, y, x+y) +} diff --git a/fa/code/src/apps/ch.3.2/main.go b/fa/code/src/apps/ch.3.2/main.go new file mode 100644 index 00000000..f8af3fdf --- /dev/null +++ b/fa/code/src/apps/ch.3.2/main.go @@ -0,0 +1,31 @@ +// Example code for Chapter 3.2 from "Build Web Application with Golang" +// Purpose: Shows how to acces the form values from the request +package main + +import ( + "fmt" + "log" + "net/http" + "strings" +) + +func sayhelloName(w http.ResponseWriter, r *http.Request) { + r.ParseForm() // parse arguments, you have to call this by yourself + fmt.Println(r.Form) // print form information in server side + fmt.Println("path", r.URL.Path) + fmt.Println("scheme", r.URL.Scheme) + fmt.Println(r.Form["url_long"]) + for k, v := range r.Form { + fmt.Println("key:", k) + fmt.Println("val:", strings.Join(v, "")) + } + fmt.Fprintf(w, "Hello astaxie!") // send data to client side +} + +func main() { + http.HandleFunc("/", sayhelloName) // set router + err := http.ListenAndServe(":9090", nil) // set listen port + if err != nil { + log.Fatal("ListenAndServe: ", err) + } +} diff --git a/fa/code/src/apps/ch.3.4/main.go b/fa/code/src/apps/ch.3.4/main.go new file mode 100644 index 00000000..fb3a5c72 --- /dev/null +++ b/fa/code/src/apps/ch.3.4/main.go @@ -0,0 +1,30 @@ +// Example code for Chapter 3.4 from "Build Web Application with Golang" +// Purpose: Shows how to create a handler for `http.ListenAndServe()` +// Run `go run main.go` then access `http://localhost:9090` +package main + +import ( + "fmt" + "net/http" +) + +type MyMux struct { +} + +func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/" { + sayhelloName(w, r) + return + } + http.NotFound(w, r) + return +} + +func sayhelloName(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hello myroute!") +} + +func main() { + mux := &MyMux{} + http.ListenAndServe(":9090", mux) +} diff --git a/fa/code/src/apps/ch.4.1/login.gtpl b/fa/code/src/apps/ch.4.1/login.gtpl new file mode 100644 index 00000000..91cd5035 --- /dev/null +++ b/fa/code/src/apps/ch.4.1/login.gtpl @@ -0,0 +1,12 @@ + + + + + +
+ Username: + Password: + +
+ + diff --git a/fa/code/src/apps/ch.4.1/main.go b/fa/code/src/apps/ch.4.1/main.go new file mode 100644 index 00000000..04daedc1 --- /dev/null +++ b/fa/code/src/apps/ch.4.1/main.go @@ -0,0 +1,48 @@ +// Example code for Chapter 4.1 from "Build Web Application with Golang" +// Purpose: Shows how to create a simple login using a template +// Run: `go run main.go`, then access `http://localhost:9090` and `http://localhost:9090/login` +package main + +import ( + "fmt" + "html/template" + "log" + "net/http" + "strings" +) + +func sayhelloName(w http.ResponseWriter, r *http.Request) { + r.ParseForm() //Parse url parameters passed, then parse the response packet for the POST body (request body) + // attention: If you do not call ParseForm method, the following data can not be obtained form + fmt.Println(r.Form) // print information on server side. + fmt.Println("path", r.URL.Path) + fmt.Println("scheme", r.URL.Scheme) + fmt.Println(r.Form["url_long"]) + for k, v := range r.Form { + fmt.Println("key:", k) + fmt.Println("val:", strings.Join(v, "")) + } + fmt.Fprintf(w, "Hello astaxie!") // write data to response +} + +func login(w http.ResponseWriter, r *http.Request) { + fmt.Println("method:", r.Method) //get request method + if r.Method == "GET" { + t, _ := template.ParseFiles("login.gtpl") + t.Execute(w, nil) + } else { + r.ParseForm() + // logic part of log in + fmt.Println("username:", r.Form["username"]) + fmt.Println("password:", r.Form["password"]) + } +} + +func main() { + http.HandleFunc("/", sayhelloName) // setting router rule + http.HandleFunc("/login", login) + err := http.ListenAndServe(":9090", nil) // setting listening port + if err != nil { + log.Fatal("ListenAndServe: ", err) + } +} diff --git a/fa/code/src/apps/ch.4.2/main.go b/fa/code/src/apps/ch.4.2/main.go new file mode 100644 index 00000000..63284146 --- /dev/null +++ b/fa/code/src/apps/ch.4.2/main.go @@ -0,0 +1,59 @@ +// Example code for Chapter 4.2 from "Build Web Application with Golang" +// Purpose: Shows how to perform server-side validation of user input from a form. +// Also shows to use multiple template files with predefined template names. +// Run `go run main.go` and then access http://localhost:9090 +package main + +import ( + "apps/ch.4.2/validator" + "html/template" + "log" + "net/http" +) + +const ( + PORT = "9090" + HOST_URL = "http://localhost:" + PORT +) + +var t *template.Template + +type Links struct { + BadLinks [][2]string +} + +// invalid links to display for testing. +var links Links + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, HOST_URL+"/profile", http.StatusTemporaryRedirect) +} +func profileHandler(w http.ResponseWriter, r *http.Request) { + t.ExecuteTemplate(w, "profile", links) +} +func checkProfile(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + p := validator.ProfilePage{&r.Form} + t.ExecuteTemplate(w, "submission", p.GetErrors()) +} + +// This function is called before main() +func init() { + // Note: we can reference the loaded templates by their defined name inside the template files. + t = template.Must(template.ParseFiles("profile.gtpl", "submission.gtpl")) + + list := make([][2]string, 2) + list[0] = [2]string{HOST_URL + "/checkprofile", "No data"} + list[1] = [2]string{HOST_URL + "/checkprofile?age=1&gender=guy&shirtsize=big", "Invalid options"} + links = Links{list} +} +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/profile", profileHandler) + http.HandleFunc("/checkprofile", checkProfile) + + err := http.ListenAndServe(":"+PORT, nil) // setting listening port + if err != nil { + log.Fatal("ListenAndServe: ", err) + } +} diff --git a/fa/code/src/apps/ch.4.2/profile.gtpl b/fa/code/src/apps/ch.4.2/profile.gtpl new file mode 100644 index 00000000..2eca7a8f --- /dev/null +++ b/fa/code/src/apps/ch.4.2/profile.gtpl @@ -0,0 +1,89 @@ +{{define "profile"}} + + + +

Profile Setup:

+
+
+
*User Name:
+
+
+
+
*Age:
+
+
+
+
*Email:
+
+
+
+
*Birth day:
+
+ +
+
+
+
Gender:
+
+ + + +
+
+
+
Siblings:
+
+ + +
+
+
+
Shirt Size:
+
+ +
+
+
+
Chinese Name:
+
+
+
+ *Required +
+ +
+

Invalid submissions

+
    {{range .BadLinks}} +
  1. {{index . 1}}
  2. + {{end}} +
+ + +{{end}} \ No newline at end of file diff --git a/fa/code/src/apps/ch.4.2/submission.gtpl b/fa/code/src/apps/ch.4.2/submission.gtpl new file mode 100644 index 00000000..fdeceed6 --- /dev/null +++ b/fa/code/src/apps/ch.4.2/submission.gtpl @@ -0,0 +1,16 @@ +{{define "submission"}} + + + {{if .Errors}} +

Errors:

+
    + {{range .Errors}} +
  1. {{.}}
  2. + {{end}} +
+ {{else}} + Profile successfully submitted. + {{end}} + + +{{end}} \ No newline at end of file diff --git a/fa/code/src/apps/ch.4.2/validator/main.go b/fa/code/src/apps/ch.4.2/validator/main.go new file mode 100644 index 00000000..35111231 --- /dev/null +++ b/fa/code/src/apps/ch.4.2/validator/main.go @@ -0,0 +1,175 @@ +// This file contains all the validators to validate the profile page. +package validator + +import ( + "errors" + "fmt" + "net/url" + "regexp" + "strconv" + "strings" + "time" +) + +type ProfilePage struct { + Form *url.Values +} +type Errors struct { + Errors []error +} + +// Goes through the form object and validates each element. +// Attachs an error to the output if validation fails. +func (p *ProfilePage) GetErrors() Errors { + errs := make([]error, 0, 10) + if *p.Form == nil || len(*p.Form) < 1 { + errs = append(errs, errors.New("No data was received. Please submit from the profile page.")) + } + for name, val := range *p.Form { + if fn, ok := stringValidator[name]; ok { + if err := fn(strings.Join(val, "")); err != nil { + errs = append(errs, err) + } + } else { + if fn, ok := stringsValidator[name]; ok { + if err := fn(val); err != nil { + errs = append(errs, err) + } + } + } + } + return Errors{errs} +} + +const ( + // Used for parsing the time + mmddyyyyForm = "01/02/2006" // we want the date sent in this format + yyyymmddForm = "2006-01-02" // However, HTML5 pages send the date in this format +) + +var stringValidator map[string]func(string) error = map[string]func(string) error{ + // parameter name : validator reference + "age": checkAge, + "birthday": checkDate, + "chineseName": checkChineseName, + "email": checkEmail, + "gender": checkGender, + "shirtsize": checkShirtSize, + "username": checkUsername, +} +var stringsValidator map[string]func([]string) error = map[string]func([]string) error{ + // parameter name : validator reference + "sibling": checkSibling, +} + +// Returns true if slices have a common element +func doSlicesIntersect(s1, s2 []string) bool { + if s1 == nil || s2 == nil { + return false + } + for _, str := range s1 { + if isElementInSlice(str, s2) { + return true + } + } + return false +} +func isElementInSlice(str string, sl []string) bool { + if sl == nil || str == "" { + return false + } + for _, v := range sl { + if v == str { + return true + } + } + return false +} + +// Checks if all the characters are chinese characters. Won't check if empty.' +func checkChineseName(str string) error { + if str != "" { + if m, _ := regexp.MatchString("^[\\x{4e00}-\\x{9fa5}]+$", strings.Trim(str, " ")); !m { + return errors.New("Please make sure that the chinese name only contains chinese characters.") + } + } + return nil +} + +// Checks if a user name exist. +func checkUsername(str string) error { + if strings.Trim(str, " ") == "" { + return errors.New("Please enter a username.") + } + return nil +} + +// Check if age is a number and between 13 and 130 +func checkAge(str string) error { + age, err := strconv.Atoi(str) + if str == "" || err != nil { + return errors.New("Please enter a valid age.") + } + if age < 13 { + return errors.New("You must be at least 13 years of age to submit.") + } + if age > 130 { + return errors.New("You're too old to register, grandpa.") + } + return nil +} +func checkEmail(str string) error { + if m, err := regexp.MatchString(`^[^@]+@[^@]+$`, str); !m { + fmt.Println("err = ", err) + return errors.New("Please enter a valid email address.") + } + return nil +} + +// Checks if a valid date was passed. +func checkDate(str string) error { + _, err := time.Parse(mmddyyyyForm, str) + if err != nil { + _, err = time.Parse(yyyymmddForm, str) + } + if str == "" || err != nil { + return errors.New("Please enter a valid Date.") + } + return nil +} + +// Checks if the passed input is a known gender option +func checkGender(str string) error { + if str == "" { + return nil + } + siblings := []string{"m", "f", "na"} + if !isElementInSlice(str, siblings) { + return errors.New("Please select a valid gender.") + } + return nil +} + +// Check if all the values are known options. +func checkSibling(strs []string) error { + if strs == nil || len(strs) < 1 { + return nil + } + siblings := []string{"m", "f"} + if siblings != nil && !doSlicesIntersect(siblings, strs) { + return errors.New("Please select a valid sibling") + } + return nil +} + +// Checks if the shirt size is a known option. +func checkShirtSize(str string) error { + if str == "" { + return nil + } + shirts := []string{"s", "m", "l", "xl", "xxl"} + if !isElementInSlice(str, shirts) { + return errors.New("Please select a valid shirt size") + } + return nil +} diff --git a/fa/code/src/apps/ch.4.3/index.gtpl b/fa/code/src/apps/ch.4.3/index.gtpl new file mode 100644 index 00000000..f8ac28fe --- /dev/null +++ b/fa/code/src/apps/ch.4.3/index.gtpl @@ -0,0 +1,28 @@ + + + +

Cross Site Scripting Attack Test

+ {{if .}} + Previous User Input:
+ +
{{.}}
+ {{end}} +
+ +
+ +
+ +
+ + + diff --git a/fa/code/src/apps/ch.4.3/main.go b/fa/code/src/apps/ch.4.3/main.go new file mode 100644 index 00000000..20b9d454 --- /dev/null +++ b/fa/code/src/apps/ch.4.3/main.go @@ -0,0 +1,39 @@ +// Example code for Chapter 4.3 from "Build Web Application with Golang" +// Purpose: Shows how to properly escape input +package main + +import ( + "html/template" + "net/http" + textTemplate "text/template" +) + +var t *template.Template = template.Must(template.ParseFiles("index.gtpl")) + +func index(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + userInput := r.Form.Get("userinput") + if 0 < len(r.Form.Get("escape")) { + t.Execute(w, template.HTMLEscapeString(userInput)) + } else { + // Variables with type `template.HTML` are not escaped when passed to `.Execute()` + t.Execute(w, template.HTML(userInput)) + } +} +func templateHandler(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + userInput := r.Form.Get("userinput") + if 0 < len(r.Form.Get("escape")) { + // `html/template.Execute()` escapes input + t.Execute(w, userInput) + } else { + tt := textTemplate.Must(textTemplate.ParseFiles("index.gtpl")) + // `text/template.Execute()` doesn't escape input + tt.Execute(w, userInput) + } +} +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/template", templateHandler) + http.ListenAndServe(":9090", nil) +} diff --git a/fa/code/src/apps/ch.4.4/main.go b/fa/code/src/apps/ch.4.4/main.go new file mode 100644 index 00000000..280f7ef1 --- /dev/null +++ b/fa/code/src/apps/ch.4.4/main.go @@ -0,0 +1,54 @@ +// Example code for Chapter 3.2 from "Build Web Application with Golang" +// Purpose: Shows how to prevent duplicate submissions by using tokens +// Example code for Chapter 4.4 based off the code from Chapter 4.2 +// Run `go run main.go` then access http://localhost:9090 +package main + +import ( + "apps/ch.4.4/nonce" + "apps/ch.4.4/validator" + "html/template" + "log" + "net/http" +) + +const ( + PORT = "9090" + HOST_URL = "http://localhost:" + PORT +) + +var submissions nonce.Nonces +var t *template.Template + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, HOST_URL+"/profile", http.StatusTemporaryRedirect) +} +func profileHandler(w http.ResponseWriter, r *http.Request) { + t.ExecuteTemplate(w, "profile", submissions.NewNonce()) +} +func checkProfile(w http.ResponseWriter, r *http.Request) { + var errs validator.Errors + r.ParseForm() + token := r.Form.Get("token") + if err := submissions.CheckThenMarkToken(token); err != nil { + errs = validator.Errors{[]error{err}} + } else { + p := validator.ProfilePage{&r.Form} + errs = p.GetErrors() + } + t.ExecuteTemplate(w, "submission", errs) +} +func init() { + submissions = nonce.New() + t = template.Must(template.ParseFiles("profile.gtpl", "submission.gtpl")) +} +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/profile", profileHandler) + http.HandleFunc("/checkprofile", checkProfile) + + err := http.ListenAndServe(":"+PORT, nil) // setting listening port + if err != nil { + log.Fatal("ListenAndServe: ", err) + } +} diff --git a/fa/code/src/apps/ch.4.4/nonce/main.go b/fa/code/src/apps/ch.4.4/nonce/main.go new file mode 100644 index 00000000..2e1663fe --- /dev/null +++ b/fa/code/src/apps/ch.4.4/nonce/main.go @@ -0,0 +1,70 @@ +// A nonce is a number or string used only once. +// This is useful for generating a unique token for login pages to prevent duplicate submissions. +package nonce + +import ( + "crypto/md5" + "errors" + "fmt" + "io" + "math/rand" + "strconv" + "time" +) + +// Contains a unique token +type Nonce struct { + Token string +} + +// Keeps track of marked/used tokens +type Nonces struct { + hashs map[string]bool +} + +func New() Nonces { + return Nonces{make(map[string]bool)} +} +func (n *Nonces) NewNonce() Nonce { + return Nonce{n.NewToken()} +} + +// Returns a new unique token +func (n *Nonces) NewToken() string { + t := createToken() + for n.HasToken(t) { + t = createToken() + } + return t +} + +// Checks if token has been marked. +func (n *Nonces) HasToken(token string) bool { + return n.hashs[token] == true +} +func (n *Nonces) MarkToken(token string) { + n.hashs[token] = true +} +func (n *Nonces) CheckToken(token string) error { + if token == "" { + return errors.New("No token supplied") + } + if n.HasToken(token) { + return errors.New("Duplicate submission.") + } + return nil +} +func (n *Nonces) CheckThenMarkToken(token string) error { + defer n.MarkToken(token) + if err := n.CheckToken(token); err != nil { + return err + } + return nil +} +func createToken() string { + h := md5.New() + now := time.Now().Unix() + io.WriteString(h, strconv.FormatInt(now, 10)) + io.WriteString(h, strconv.FormatInt(rand.Int63(), 10)) + return fmt.Sprintf("%x", h.Sum(nil)) +} diff --git a/fa/code/src/apps/ch.4.4/profile.gtpl b/fa/code/src/apps/ch.4.4/profile.gtpl new file mode 100644 index 00000000..34833086 --- /dev/null +++ b/fa/code/src/apps/ch.4.4/profile.gtpl @@ -0,0 +1,85 @@ +{{define "profile"}} + + + +

Profile Setup:

+
+
+
*User Name:
+
+
+
+
*Age:
+
+
+
+
*Email:
+
+
+
+
*Birth day:
+
+ +
+
+
+
Gender:
+
+ + + +
+
+
+
Siblings:
+
+ + +
+
+
+
Shirt Size:
+
+ +
+
+
+
Chinese Name:
+
+
+
+ *Required +
+ + +
+ + +{{end}} diff --git a/fa/code/src/apps/ch.4.4/submission.gtpl b/fa/code/src/apps/ch.4.4/submission.gtpl new file mode 100644 index 00000000..456ff678 --- /dev/null +++ b/fa/code/src/apps/ch.4.4/submission.gtpl @@ -0,0 +1,17 @@ +{{define "submission"}} + + + {{if .Errors}} +

Errors:

+
    + {{range .Errors}} +
  1. {{.}}
  2. + {{end}} +
+ {{else}} + Profile successfully submitted.
+ Note: Refreshing the page will produce a duplicate entry. + {{end}} + + +{{end}} \ No newline at end of file diff --git a/fa/code/src/apps/ch.4.4/validator/main.go b/fa/code/src/apps/ch.4.4/validator/main.go new file mode 100644 index 00000000..35111231 --- /dev/null +++ b/fa/code/src/apps/ch.4.4/validator/main.go @@ -0,0 +1,175 @@ +// This file contains all the validators to validate the profile page. +package validator + +import ( + "errors" + "fmt" + "net/url" + "regexp" + "strconv" + "strings" + "time" +) + +type ProfilePage struct { + Form *url.Values +} +type Errors struct { + Errors []error +} + +// Goes through the form object and validates each element. +// Attachs an error to the output if validation fails. +func (p *ProfilePage) GetErrors() Errors { + errs := make([]error, 0, 10) + if *p.Form == nil || len(*p.Form) < 1 { + errs = append(errs, errors.New("No data was received. Please submit from the profile page.")) + } + for name, val := range *p.Form { + if fn, ok := stringValidator[name]; ok { + if err := fn(strings.Join(val, "")); err != nil { + errs = append(errs, err) + } + } else { + if fn, ok := stringsValidator[name]; ok { + if err := fn(val); err != nil { + errs = append(errs, err) + } + } + } + } + return Errors{errs} +} + +const ( + // Used for parsing the time + mmddyyyyForm = "01/02/2006" // we want the date sent in this format + yyyymmddForm = "2006-01-02" // However, HTML5 pages send the date in this format +) + +var stringValidator map[string]func(string) error = map[string]func(string) error{ + // parameter name : validator reference + "age": checkAge, + "birthday": checkDate, + "chineseName": checkChineseName, + "email": checkEmail, + "gender": checkGender, + "shirtsize": checkShirtSize, + "username": checkUsername, +} +var stringsValidator map[string]func([]string) error = map[string]func([]string) error{ + // parameter name : validator reference + "sibling": checkSibling, +} + +// Returns true if slices have a common element +func doSlicesIntersect(s1, s2 []string) bool { + if s1 == nil || s2 == nil { + return false + } + for _, str := range s1 { + if isElementInSlice(str, s2) { + return true + } + } + return false +} +func isElementInSlice(str string, sl []string) bool { + if sl == nil || str == "" { + return false + } + for _, v := range sl { + if v == str { + return true + } + } + return false +} + +// Checks if all the characters are chinese characters. Won't check if empty.' +func checkChineseName(str string) error { + if str != "" { + if m, _ := regexp.MatchString("^[\\x{4e00}-\\x{9fa5}]+$", strings.Trim(str, " ")); !m { + return errors.New("Please make sure that the chinese name only contains chinese characters.") + } + } + return nil +} + +// Checks if a user name exist. +func checkUsername(str string) error { + if strings.Trim(str, " ") == "" { + return errors.New("Please enter a username.") + } + return nil +} + +// Check if age is a number and between 13 and 130 +func checkAge(str string) error { + age, err := strconv.Atoi(str) + if str == "" || err != nil { + return errors.New("Please enter a valid age.") + } + if age < 13 { + return errors.New("You must be at least 13 years of age to submit.") + } + if age > 130 { + return errors.New("You're too old to register, grandpa.") + } + return nil +} +func checkEmail(str string) error { + if m, err := regexp.MatchString(`^[^@]+@[^@]+$`, str); !m { + fmt.Println("err = ", err) + return errors.New("Please enter a valid email address.") + } + return nil +} + +// Checks if a valid date was passed. +func checkDate(str string) error { + _, err := time.Parse(mmddyyyyForm, str) + if err != nil { + _, err = time.Parse(yyyymmddForm, str) + } + if str == "" || err != nil { + return errors.New("Please enter a valid Date.") + } + return nil +} + +// Checks if the passed input is a known gender option +func checkGender(str string) error { + if str == "" { + return nil + } + siblings := []string{"m", "f", "na"} + if !isElementInSlice(str, siblings) { + return errors.New("Please select a valid gender.") + } + return nil +} + +// Check if all the values are known options. +func checkSibling(strs []string) error { + if strs == nil || len(strs) < 1 { + return nil + } + siblings := []string{"m", "f"} + if siblings != nil && !doSlicesIntersect(siblings, strs) { + return errors.New("Please select a valid sibling") + } + return nil +} + +// Checks if the shirt size is a known option. +func checkShirtSize(str string) error { + if str == "" { + return nil + } + shirts := []string{"s", "m", "l", "xl", "xxl"} + if !isElementInSlice(str, shirts) { + return errors.New("Please select a valid shirt size") + } + return nil +} diff --git a/fa/code/src/apps/ch.4.5/client_upload/main.go b/fa/code/src/apps/ch.4.5/client_upload/main.go new file mode 100644 index 00000000..5757cc77 --- /dev/null +++ b/fa/code/src/apps/ch.4.5/client_upload/main.go @@ -0,0 +1,46 @@ +package main + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "mime/multipart" + "net/http" + "os" +) + +func checkError(err error) { + if err != nil { + panic(err) + } +} +func postFile(filename string, targetUrl string) { + bodyBuf := &bytes.Buffer{} + bodyWriter := multipart.NewWriter(bodyBuf) + fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename) + checkError(err) + + fh, err := os.Open(filename) + checkError(err) + + _, err = io.Copy(fileWriter, fh) + checkError(err) + + contentType := bodyWriter.FormDataContentType() + bodyWriter.Close() + resp, err := http.Post(targetUrl, contentType, bodyBuf) + checkError(err) + + defer resp.Body.Close() + resp_body, err := ioutil.ReadAll(resp.Body) + checkError(err) + + fmt.Println(resp.Status) + fmt.Println(string(resp_body)) +} +func main() { + target_url := "http://localhost:9090/upload" + filename := "../file.txt" + postFile(filename, target_url) +} diff --git a/fa/code/src/apps/ch.4.5/index.gtpl b/fa/code/src/apps/ch.4.5/index.gtpl new file mode 100644 index 00000000..aa1149c6 --- /dev/null +++ b/fa/code/src/apps/ch.4.5/index.gtpl @@ -0,0 +1,15 @@ +{{define "index"}} + + + + Upload file + + +
+ + + +
+ + +{{end}} diff --git a/fa/code/src/apps/ch.4.5/main.go b/fa/code/src/apps/ch.4.5/main.go new file mode 100644 index 00000000..24591dcf --- /dev/null +++ b/fa/code/src/apps/ch.4.5/main.go @@ -0,0 +1,64 @@ +// Example code for Chapter 4.5 +// Purpose is to create a server to handle uploading files. +package main + +import ( + "apps/ch.4.4/nonce" + "apps/ch.4.4/validator" + "fmt" + "html/template" + "io" + "mime/multipart" + "net/http" + "os" +) + +const MiB_UNIT = 1 << 20 + +var t *template.Template +var submissions nonce.Nonces = nonce.New() + +func checkError(err error) { + if err != nil { + panic(err) + } +} +func indexHandler(w http.ResponseWriter, r *http.Request) { + err := t.ExecuteTemplate(w, "index", submissions.NewToken()) + checkError(err) +} +func uploadHandler(w http.ResponseWriter, r *http.Request) { + var errs validator.Errors + r.ParseMultipartForm(32 * MiB_UNIT) + token := r.Form.Get("token") + if err := submissions.CheckThenMarkToken(token); err != nil { + errs = validator.Errors{[]error{err}} + } else { + file, handler, err := r.FormFile("uploadfile") + checkError(err) + saveUpload(file, handler) + } + err := t.ExecuteTemplate(w, "upload", errs) + checkError(err) +} +func saveUpload(file multipart.File, handler *multipart.FileHeader) { + defer file.Close() + fmt.Printf("Uploaded file info: %#v", handler.Header) + localFilename := fmt.Sprintf("./uploads/%v.%v", handler.Filename, submissions.NewToken()) + f, err := os.OpenFile(localFilename, os.O_WRONLY|os.O_CREATE, 0666) + checkError(err) + defer f.Close() + _, err = io.Copy(f, file) + checkError(err) +} +func init() { + var err error + t, err = template.ParseFiles("index.gtpl", "upload.gtpl") + checkError(err) +} +func main() { + http.HandleFunc("/", indexHandler) + http.HandleFunc("/upload", uploadHandler) + err := http.ListenAndServe(":9090", nil) + checkError(err) +} diff --git a/fa/code/src/apps/ch.4.5/nonce/main.go b/fa/code/src/apps/ch.4.5/nonce/main.go new file mode 100644 index 00000000..2e1663fe --- /dev/null +++ b/fa/code/src/apps/ch.4.5/nonce/main.go @@ -0,0 +1,70 @@ +// A nonce is a number or string used only once. +// This is useful for generating a unique token for login pages to prevent duplicate submissions. +package nonce + +import ( + "crypto/md5" + "errors" + "fmt" + "io" + "math/rand" + "strconv" + "time" +) + +// Contains a unique token +type Nonce struct { + Token string +} + +// Keeps track of marked/used tokens +type Nonces struct { + hashs map[string]bool +} + +func New() Nonces { + return Nonces{make(map[string]bool)} +} +func (n *Nonces) NewNonce() Nonce { + return Nonce{n.NewToken()} +} + +// Returns a new unique token +func (n *Nonces) NewToken() string { + t := createToken() + for n.HasToken(t) { + t = createToken() + } + return t +} + +// Checks if token has been marked. +func (n *Nonces) HasToken(token string) bool { + return n.hashs[token] == true +} +func (n *Nonces) MarkToken(token string) { + n.hashs[token] = true +} +func (n *Nonces) CheckToken(token string) error { + if token == "" { + return errors.New("No token supplied") + } + if n.HasToken(token) { + return errors.New("Duplicate submission.") + } + return nil +} +func (n *Nonces) CheckThenMarkToken(token string) error { + defer n.MarkToken(token) + if err := n.CheckToken(token); err != nil { + return err + } + return nil +} +func createToken() string { + h := md5.New() + now := time.Now().Unix() + io.WriteString(h, strconv.FormatInt(now, 10)) + io.WriteString(h, strconv.FormatInt(rand.Int63(), 10)) + return fmt.Sprintf("%x", h.Sum(nil)) +} diff --git a/fa/code/src/apps/ch.4.5/upload.gtpl b/fa/code/src/apps/ch.4.5/upload.gtpl new file mode 100644 index 00000000..4c55c5c5 --- /dev/null +++ b/fa/code/src/apps/ch.4.5/upload.gtpl @@ -0,0 +1,17 @@ +{{define "upload"}} + + + {{if .Errors}} +

Errors:

+
    + {{range .Errors}} +
  1. {{.}}
  2. + {{end}} +
+ {{else}} + File uploaded successfully.
+ Note: Refreshing the page will produce a duplicate entry. + {{end}} + + +{{end}} diff --git a/fa/code/src/apps/ch.4.5/validator/main.go b/fa/code/src/apps/ch.4.5/validator/main.go new file mode 100644 index 00000000..35111231 --- /dev/null +++ b/fa/code/src/apps/ch.4.5/validator/main.go @@ -0,0 +1,175 @@ +// This file contains all the validators to validate the profile page. +package validator + +import ( + "errors" + "fmt" + "net/url" + "regexp" + "strconv" + "strings" + "time" +) + +type ProfilePage struct { + Form *url.Values +} +type Errors struct { + Errors []error +} + +// Goes through the form object and validates each element. +// Attachs an error to the output if validation fails. +func (p *ProfilePage) GetErrors() Errors { + errs := make([]error, 0, 10) + if *p.Form == nil || len(*p.Form) < 1 { + errs = append(errs, errors.New("No data was received. Please submit from the profile page.")) + } + for name, val := range *p.Form { + if fn, ok := stringValidator[name]; ok { + if err := fn(strings.Join(val, "")); err != nil { + errs = append(errs, err) + } + } else { + if fn, ok := stringsValidator[name]; ok { + if err := fn(val); err != nil { + errs = append(errs, err) + } + } + } + } + return Errors{errs} +} + +const ( + // Used for parsing the time + mmddyyyyForm = "01/02/2006" // we want the date sent in this format + yyyymmddForm = "2006-01-02" // However, HTML5 pages send the date in this format +) + +var stringValidator map[string]func(string) error = map[string]func(string) error{ + // parameter name : validator reference + "age": checkAge, + "birthday": checkDate, + "chineseName": checkChineseName, + "email": checkEmail, + "gender": checkGender, + "shirtsize": checkShirtSize, + "username": checkUsername, +} +var stringsValidator map[string]func([]string) error = map[string]func([]string) error{ + // parameter name : validator reference + "sibling": checkSibling, +} + +// Returns true if slices have a common element +func doSlicesIntersect(s1, s2 []string) bool { + if s1 == nil || s2 == nil { + return false + } + for _, str := range s1 { + if isElementInSlice(str, s2) { + return true + } + } + return false +} +func isElementInSlice(str string, sl []string) bool { + if sl == nil || str == "" { + return false + } + for _, v := range sl { + if v == str { + return true + } + } + return false +} + +// Checks if all the characters are chinese characters. Won't check if empty.' +func checkChineseName(str string) error { + if str != "" { + if m, _ := regexp.MatchString("^[\\x{4e00}-\\x{9fa5}]+$", strings.Trim(str, " ")); !m { + return errors.New("Please make sure that the chinese name only contains chinese characters.") + } + } + return nil +} + +// Checks if a user name exist. +func checkUsername(str string) error { + if strings.Trim(str, " ") == "" { + return errors.New("Please enter a username.") + } + return nil +} + +// Check if age is a number and between 13 and 130 +func checkAge(str string) error { + age, err := strconv.Atoi(str) + if str == "" || err != nil { + return errors.New("Please enter a valid age.") + } + if age < 13 { + return errors.New("You must be at least 13 years of age to submit.") + } + if age > 130 { + return errors.New("You're too old to register, grandpa.") + } + return nil +} +func checkEmail(str string) error { + if m, err := regexp.MatchString(`^[^@]+@[^@]+$`, str); !m { + fmt.Println("err = ", err) + return errors.New("Please enter a valid email address.") + } + return nil +} + +// Checks if a valid date was passed. +func checkDate(str string) error { + _, err := time.Parse(mmddyyyyForm, str) + if err != nil { + _, err = time.Parse(yyyymmddForm, str) + } + if str == "" || err != nil { + return errors.New("Please enter a valid Date.") + } + return nil +} + +// Checks if the passed input is a known gender option +func checkGender(str string) error { + if str == "" { + return nil + } + siblings := []string{"m", "f", "na"} + if !isElementInSlice(str, siblings) { + return errors.New("Please select a valid gender.") + } + return nil +} + +// Check if all the values are known options. +func checkSibling(strs []string) error { + if strs == nil || len(strs) < 1 { + return nil + } + siblings := []string{"m", "f"} + if siblings != nil && !doSlicesIntersect(siblings, strs) { + return errors.New("Please select a valid sibling") + } + return nil +} + +// Checks if the shirt size is a known option. +func checkShirtSize(str string) error { + if str == "" { + return nil + } + shirts := []string{"s", "m", "l", "xl", "xxl"} + if !isElementInSlice(str, shirts) { + return errors.New("Please select a valid shirt size") + } + return nil +} diff --git a/fa/code/src/apps/ch.5.2/main.go b/fa/code/src/apps/ch.5.2/main.go new file mode 100644 index 00000000..b64c4450 --- /dev/null +++ b/fa/code/src/apps/ch.5.2/main.go @@ -0,0 +1,76 @@ +// Example code for Chapter 5.2 from "Build Web Application with Golang" +// Purpose: Use SQL driver to perform simple CRUD operations. +package main + +import ( + "database/sql" + "fmt" + _ "github.com/go-sql-driver/mysql" +) + +const ( + DB_USER = "user" + DB_PASSWORD = "" + DB_NAME = "test" +) + +func main() { + dbSouce := fmt.Sprintf("%v:%v@/%v?charset=utf8", DB_USER, DB_PASSWORD, DB_NAME) + db, err := sql.Open("mysql", dbSouce) + checkErr(err) + defer db.Close() + + fmt.Println("Inserting") + stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?") + checkErr(err) + + res, err := stmt.Exec("astaxie", "software developement", "2012-12-09") + checkErr(err) + + id, err := res.LastInsertId() + checkErr(err) + + fmt.Println("id of last inserted row =", id) + fmt.Println("Updating") + stmt, err = db.Prepare("update userinfo set username=? where uid=?") + checkErr(err) + + res, err = stmt.Exec("astaxieupdate", id) + checkErr(err) + + affect, err := res.RowsAffected() + checkErr(err) + + fmt.Println(affect, "row(s) changed") + + fmt.Println("Querying") + rows, err := db.Query("SELECT * FROM userinfo") + checkErr(err) + + for rows.Next() { + var uid int + var username, department, created string + err = rows.Scan(&uid, &username, &department, &created) + checkErr(err) + fmt.Println("uid | username | department | created") + fmt.Printf("%3v | %6v | %6v | %6v\n", uid, username, department, created) + } + + fmt.Println("Deleting") + stmt, err = db.Prepare("delete from userinfo where uid=?") + checkErr(err) + + res, err = stmt.Exec(id) + checkErr(err) + + affect, err = res.RowsAffected() + checkErr(err) + + fmt.Println(affect, "row(s) changed") +} + +func checkErr(err error) { + if err != nil { + panic(err) + } +} diff --git a/fa/code/src/apps/ch.5.2/readme.md b/fa/code/src/apps/ch.5.2/readme.md new file mode 100644 index 00000000..9e34f7d7 --- /dev/null +++ b/fa/code/src/apps/ch.5.2/readme.md @@ -0,0 +1,12 @@ +## Setup for `ch.5.2` + +- Step 1) Install and run MySql +- Step 2) Create a user and database according to the constants in `main.go` + + DB_USER = "user" + DB_PASSWORD = "" + DB_NAME = "test" + +- Step 3) Create table `userinfo` located at `schema.sql` +- Step 4) Run `go get` to download and install the remote packages. +- Step 5) Execute the program with `go run main.go` diff --git a/fa/code/src/apps/ch.5.2/schema.sql b/fa/code/src/apps/ch.5.2/schema.sql new file mode 100644 index 00000000..04128f7f --- /dev/null +++ b/fa/code/src/apps/ch.5.2/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE `userinfo` ( + `uid` INT(10) NOT NULL AUTO_INCREMENT, + `username` VARCHAR(64) NULL DEFAULT NULL, + `departname` VARCHAR(64) NULL DEFAULT NULL, + `created` DATE NULL DEFAULT NULL, + PRIMARY KEY (`uid`) +); diff --git a/fa/code/src/apps/ch.5.3/foo.db b/fa/code/src/apps/ch.5.3/foo.db new file mode 100644 index 00000000..d805156b Binary files /dev/null and b/fa/code/src/apps/ch.5.3/foo.db differ diff --git a/fa/code/src/apps/ch.5.3/main.go b/fa/code/src/apps/ch.5.3/main.go new file mode 100644 index 00000000..6f19518f --- /dev/null +++ b/fa/code/src/apps/ch.5.3/main.go @@ -0,0 +1,72 @@ +// Example code for Chapter 5.3 from "Build Web Application with Golang" +// Purpose: Shows how to run simple CRUD operations using a sqlite driver +package main + +import ( + "database/sql" + "fmt" + _ "github.com/mattn/go-sqlite3" + "time" +) + +const DB_PATH = "./foo.db" + +func main() { + db, err := sql.Open("sqlite3", DB_PATH) + checkErr(err) + defer db.Close() + + fmt.Println("Inserting") + stmt, err := db.Prepare("INSERT INTO userinfo(username, department, created) values(?,?,?)") + checkErr(err) + + res, err := stmt.Exec("astaxie", "software developement", time.Now().Format("2006-01-02")) + checkErr(err) + + id, err := res.LastInsertId() + checkErr(err) + + fmt.Println("id of last inserted row =", id) + fmt.Println("Updating") + stmt, err = db.Prepare("update userinfo set username=? where uid=?") + checkErr(err) + + res, err = stmt.Exec("astaxieupdate", id) + checkErr(err) + + affect, err := res.RowsAffected() + checkErr(err) + + fmt.Println(affect, "row(s) changed") + + fmt.Println("Querying") + rows, err := db.Query("SELECT * FROM userinfo") + checkErr(err) + + for rows.Next() { + var uid int + var username, department, created string + err = rows.Scan(&uid, &username, &department, &created) + checkErr(err) + fmt.Println("uid | username | department | created") + fmt.Printf("%3v | %6v | %8v | %6v\n", uid, username, department, created) + } + + fmt.Println("Deleting") + stmt, err = db.Prepare("delete from userinfo where uid=?") + checkErr(err) + + res, err = stmt.Exec(id) + checkErr(err) + + affect, err = res.RowsAffected() + checkErr(err) + + fmt.Println(affect, "row(s) changed") +} + +func checkErr(err error) { + if err != nil { + panic(err) + } +} diff --git a/fa/code/src/apps/ch.5.3/readme.md b/fa/code/src/apps/ch.5.3/readme.md new file mode 100644 index 00000000..8ca48a7b --- /dev/null +++ b/fa/code/src/apps/ch.5.3/readme.md @@ -0,0 +1,23 @@ +## Set up for `ch.5.3` + +- Step 1) Download and install sqlite 3. +- Step 2) Run `sqlite3 foo.db` to create a databased called `foo`. +- Step 3) Create the `userinfo` table in sqlite using `schema.sql`. + + Read and run sql statements + + sqlite> .read schema.sql + + Show tables + + sqlite> .tables + userinfo + + +- Step 4) Exit sqlite. + + sqlite> .exit + +- Step 5) Run `go get` to download and install remote packages. +- Step 6) Run the program with `go run main.go` + diff --git a/fa/code/src/apps/ch.5.3/schema.sql b/fa/code/src/apps/ch.5.3/schema.sql new file mode 100644 index 00000000..55aebb48 --- /dev/null +++ b/fa/code/src/apps/ch.5.3/schema.sql @@ -0,0 +1,6 @@ +CREATE TABLE `userinfo` ( + `uid` INTEGER PRIMARY KEY AUTOINCREMENT, + `username` VARCHAR(64) NULL, + `department` VARCHAR(64) NULL, + `created` DATE NULL + ); diff --git a/fa/code/src/apps/ch.5.4/main.go b/fa/code/src/apps/ch.5.4/main.go new file mode 100644 index 00000000..3b7afdaf --- /dev/null +++ b/fa/code/src/apps/ch.5.4/main.go @@ -0,0 +1,78 @@ +// Example code for Chapter 5.4 from "Build Web Application with Golang" +// Purpose: Show how to perform CRUD operations using a postgres driver +package main + +import ( + "database/sql" + "fmt" + "time" + + _ "github.com/lib/pq" +) + +const ( + DB_USER = "user" + DB_PASSWORD = "" + DB_NAME = "test" +) + +func main() { + dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable", + DB_USER, DB_PASSWORD, DB_NAME) + db, err := sql.Open("postgres", dbinfo) + checkErr(err) + defer db.Close() + + fmt.Println("# Inserting values") + + var lastInsertId int + err = db.QueryRow("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) returning uid;", + "astaxie", "software developement", "2012-12-09").Scan(&lastInsertId) + checkErr(err) + fmt.Println("id of last inserted row =", lastInsertId) + + fmt.Println("# Updating") + stmt, err := db.Prepare("update userinfo set username=$1 where uid=$2") + checkErr(err) + + res, err := stmt.Exec("astaxieupdate", lastInsertId) + checkErr(err) + + affect, err := res.RowsAffected() + checkErr(err) + + fmt.Println(affect, "row(s) changed") + + fmt.Println("# Querying") + rows, err := db.Query("SELECT * FROM userinfo") + checkErr(err) + + for rows.Next() { + var uid int + var username string + var department string + var created time.Time + err = rows.Scan(&uid, &username, &department, &created) + checkErr(err) + fmt.Println("uid | username | department | created ") + fmt.Printf("%3v | %8v | %6v | %6v\n", uid, username, department, created) + } + + fmt.Println("# Deleting") + stmt, err = db.Prepare("delete from userinfo where uid=$1") + checkErr(err) + + res, err = stmt.Exec(lastInsertId) + checkErr(err) + + affect, err = res.RowsAffected() + checkErr(err) + + fmt.Println(affect, "row(s) changed") +} + +func checkErr(err error) { + if err != nil { + panic(err) + } +} diff --git a/fa/code/src/apps/ch.5.4/readme.md b/fa/code/src/apps/ch.5.4/readme.md new file mode 100644 index 00000000..74f1e2a3 --- /dev/null +++ b/fa/code/src/apps/ch.5.4/readme.md @@ -0,0 +1,12 @@ +## Setup for ch.5.4 + +- Step 1) Install and run Postgres +- Step 2) Create a user and database according to the constants in `main.go` + + DB_USER = "user" + DB_PASSWORD = "" + DB_NAME = "test" + +- Step 3) Create table `userinfo` located at `schema.sql` +- Step 4) Run `go get` to download and install the remote packages. +- Step 5) Execute the program with `go run main.go` diff --git a/fa/code/src/apps/ch.5.4/schema.sql b/fa/code/src/apps/ch.5.4/schema.sql new file mode 100644 index 00000000..001e8433 --- /dev/null +++ b/fa/code/src/apps/ch.5.4/schema.sql @@ -0,0 +1,9 @@ +CREATE TABLE userinfo +( + uid serial NOT NULL, + username character varying(100) NOT NULL, + departname character varying(500) NOT NULL, + Created date, + CONSTRAINT userinfo_pkey PRIMARY KEY (uid) +) +WITH (OIDS=FALSE); diff --git a/fa/code/src/apps/ch.5.5/main.go b/fa/code/src/apps/ch.5.5/main.go new file mode 100644 index 00000000..ce90e960 --- /dev/null +++ b/fa/code/src/apps/ch.5.5/main.go @@ -0,0 +1,170 @@ +// Example code for Chapter 5.5 +// Purpose is to show to use BeeDB ORM for basic CRUD operations for sqlite3 +package main + +import ( + "database/sql" + "fmt" + "github.com/astaxie/beedb" + _ "github.com/mattn/go-sqlite3" + "time" +) + +var orm beedb.Model + +type Userinfo struct { + Uid int `beedb:"PK"` + Username string + Department string + Created string +} + +const DB_PATH = "./foo.db" + +func checkError(err error) { + if err != nil { + panic(err) + } +} +func getTimeStamp() string { + return time.Now().Format("2006-01-02 15:04:05") +} +func insertUsingStruct() int64 { + fmt.Println("insertUsingStruct()") + var obj Userinfo + obj.Username = "Test Add User" + obj.Department = "Test Add Department" + obj.Created = getTimeStamp() + checkError(orm.Save(&obj)) + fmt.Printf("%+v\n", obj) + return int64(obj.Uid) +} +func insertUsingMap() int64 { + fmt.Println("insertUsingMap()") + add := make(map[string]interface{}) + add["username"] = "astaxie" + add["department"] = "cloud develop" + add["created"] = getTimeStamp() + id, err := orm.SetTable("userinfo").Insert(add) + checkError(err) + fmt.Println("Last row inserted id =", id) + return id +} + +func getOneUserInfo(id int64) Userinfo { + fmt.Println("getOneUserInfo()") + var obj Userinfo + checkError(orm.Where("uid=?", id).Find(&obj)) + return obj +} + +func getAllUserInfo(id int64) []Userinfo { + fmt.Println("getAllUserInfo()") + var alluser []Userinfo + checkError(orm.Limit(10).Where("uid>?", id).FindAll(&alluser)) + return alluser +} + +func updateUserinfo(id int64) { + fmt.Println("updateUserinfo()") + var obj Userinfo + obj.Uid = int(id) + obj.Username = "Update Username" + obj.Department = "Update Department" + obj.Created = getTimeStamp() + checkError(orm.Save(&obj)) + fmt.Printf("%+v\n", obj) +} + +func updateUsingMap(id int64) { + fmt.Println("updateUsingMap()") + t := make(map[string]interface{}) + t["username"] = "updateastaxie" + //update one + // id, err := orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t) + //update batch + lastId, err := orm.SetTable("userinfo").Where("uid>?", id).Update(t) + checkError(err) + fmt.Println("Last row updated id =", lastId) +} + +func getMapsFromSelect(id int64) []map[string][]byte { + fmt.Println("getMapsFromSelect()") + //Original SQL Backinfo resultsSlice []map[string][]byte + //default PrimaryKey id + c, err := orm.SetTable("userinfo").SetPK("uid").Where(id).Select("uid,username").FindMap() + checkError(err) + fmt.Printf("%+v\n", c) + return c +} + +func groupby() { + fmt.Println("groupby()") + //Original SQL Group By + b, err := orm.SetTable("userinfo").GroupBy("username").Having("username='updateastaxie'").FindMap() + checkError(err) + fmt.Printf("%+v\n", b) +} + +func joinTables(id int64) { + fmt.Println("joinTables()") + //Original SQL Join Table + a, err := orm.SetTable("userinfo").Join("LEFT", "userdetail", "userinfo.uid=userdetail.uid").Where("userinfo.uid=?", id).Select("userinfo.uid,userinfo.username,userdetail.profile").FindMap() + checkError(err) + fmt.Printf("%+v\n", a) +} + +func deleteWithUserinfo(id int64) { + fmt.Println("deleteWithUserinfo()") + obj := getOneUserInfo(id) + id, err := orm.Delete(&obj) + checkError(err) + fmt.Println("Last row deleted id =", id) +} + +func deleteRows() { + fmt.Println("deleteRows()") + //original SQL delete + id, err := orm.SetTable("userinfo").Where("uid>?", 2).DeleteRow() + checkError(err) + fmt.Println("Last row updated id =", id) +} + +func deleteAllUserinfo(id int64) { + fmt.Println("deleteAllUserinfo()") + //delete all data + alluser := getAllUserInfo(id) + id, err := orm.DeleteAll(&alluser) + checkError(err) + fmt.Println("Last row updated id =", id) +} +func main() { + db, err := sql.Open("sqlite3", DB_PATH) + checkError(err) + orm = beedb.New(db) + var lastIdInserted int64 + + fmt.Println("Inserting") + lastIdInserted = insertUsingStruct() + insertUsingMap() + + a := getOneUserInfo(lastIdInserted) + fmt.Println(a) + + b := getAllUserInfo(lastIdInserted) + fmt.Println(b) + + fmt.Println("Updating") + updateUserinfo(lastIdInserted) + updateUsingMap(lastIdInserted) + + fmt.Println("Querying") + getMapsFromSelect(lastIdInserted) + groupby() + joinTables(lastIdInserted) + + fmt.Println("Deleting") + deleteWithUserinfo(lastIdInserted) + deleteRows() + deleteAllUserinfo(lastIdInserted) +} diff --git a/fa/code/src/apps/ch.5.5/readme.md b/fa/code/src/apps/ch.5.5/readme.md new file mode 100644 index 00000000..fcad11c8 --- /dev/null +++ b/fa/code/src/apps/ch.5.5/readme.md @@ -0,0 +1,23 @@ +## Set up for `ch.5.5` + +- Step 1) Download and install sqlite 3. +- Step 2) Run `sqlite3 foo.db` to create a databased called `foo`. +- Step 3) Create the tables found in `schema.sql` in sqlite. + + Read and run sql statements + + sqlite> .read schema.sql + + Show tables + + sqlite> .tables + userinfo + userdetail + +- Step 4) Exit sqlite. + + sqlite> .exit + +- Step 5) Run `go get` to download and install remote packages. +- Step 6) Run the program with `go run main.go` + diff --git a/fa/code/src/apps/ch.5.5/schema.sql b/fa/code/src/apps/ch.5.5/schema.sql new file mode 100644 index 00000000..da897d5f --- /dev/null +++ b/fa/code/src/apps/ch.5.5/schema.sql @@ -0,0 +1,12 @@ +CREATE TABLE `userinfo` ( + `uid` INTEGER PRIMARY KEY AUTOINCREMENT, + `username` VARCHAR(64) NULL, + `department` VARCHAR(64) NULL, + `created` DATE NULL +); +CREATE TABLE `userdetail` ( + `uid` INT(10) NULL, + `intro` TEXT NULL, + `profile` TEXT NULL, + PRIMARY KEY (`uid`) +); diff --git a/fa/code/src/apps/ch.5.6/mongodb/main.go b/fa/code/src/apps/ch.5.6/mongodb/main.go new file mode 100644 index 00000000..9013f5ae --- /dev/null +++ b/fa/code/src/apps/ch.5.6/mongodb/main.go @@ -0,0 +1,58 @@ +// Example code for Chapter 5.6 from "Build Web Application with Golang" +// Purpose: Shows you have to perform basic CRUD operations for a mongodb driver. +package main + +import ( + "fmt" + "labix.org/v2/mgo" + "labix.org/v2/mgo/bson" +) + +type Person struct { + Name string + Phone string +} + +func checkError(err error) { + if err != nil { + panic(err) + } +} + +const ( + DB_NAME = "test" + DB_COLLECTION = "people" +) + +func main() { + session, err := mgo.Dial("localhost") + checkError(err) + defer session.Close() + + session.SetMode(mgo.Monotonic, true) + + c := session.DB(DB_NAME).C(DB_COLLECTION) + err = c.DropCollection() + checkError(err) + + ale := Person{"Ale", "555-5555"} + cla := Person{"Cla", "555-1234"} + + fmt.Println("Inserting") + err = c.Insert(&ale, &cla) + checkError(err) + + fmt.Println("Updating") + ale.Phone = "555-0101" + err = c.Update(bson.M{"name": "Ale"}, &ale) + + fmt.Println("Querying") + result := Person{} + err = c.Find(bson.M{"name": "Ale"}).One(&result) + checkError(err) + fmt.Println("Phone:", result.Phone) + + fmt.Println("Deleting") + err = c.Remove(bson.M{"name": "Ale"}) + checkError(err) +} diff --git a/fa/code/src/apps/ch.5.6/mongodb/readme.md b/fa/code/src/apps/ch.5.6/mongodb/readme.md new file mode 100644 index 00000000..35bee2fe --- /dev/null +++ b/fa/code/src/apps/ch.5.6/mongodb/readme.md @@ -0,0 +1,6 @@ +## Setup for `ch.5.6` for MongoDB + +- Step 1) Install and run MongoDB +- Step 2) Launch the MongoDB daemon (mongod) to start the server. +- Step 3) Run `go get` to download and install the remote packages. +- Step 4) Execute the program with `go run main.go` diff --git a/fa/code/src/apps/ch.5.6/redis/main.go b/fa/code/src/apps/ch.5.6/redis/main.go new file mode 100644 index 00000000..9bac3f30 --- /dev/null +++ b/fa/code/src/apps/ch.5.6/redis/main.go @@ -0,0 +1,60 @@ +// Example code for Chapter 5.6 from "Build Web Application with Golang" +// Purpose: Shows you have to perform basic CRUD operations for a redis driver. +package main + +import ( + "fmt" + "github.com/astaxie/goredis" +) + +func checkError(err error) { + if err != nil { + panic(err) + } +} + +const ( + DB_PORT = "9191" + DB_URL = "127.0.0.1" +) + +func main() { + var client goredis.Client + + // Set the default port in Redis + client.Addr = DB_URL + ":" + DB_PORT + + // string manipulation + fmt.Println("Inserting") + err := client.Set("a", []byte("hello")) + checkError(err) + + // list operation + vals := []string{"a", "b", "c", "d"} + for _, v := range vals { + err = client.Rpush("l", []byte(v)) + checkError(err) + } + fmt.Println("Updating") + err = client.Set("a", []byte("a is for apple")) + checkError(err) + err = client.Rpush("l", []byte("e")) + checkError(err) + + fmt.Println("Querying") + val, err := client.Get("a") + checkError(err) + fmt.Println(string(val)) + + dbvals, err := client.Lrange("l", 0, 4) + checkError(err) + for i, v := range dbvals { + println(i, ":", string(v)) + } + + fmt.Println("Deleting") + _, err = client.Del("l") + checkError(err) + _, err = client.Del("a") + checkError(err) +} diff --git a/fa/code/src/apps/ch.5.6/redis/readme.md b/fa/code/src/apps/ch.5.6/redis/readme.md new file mode 100644 index 00000000..4965e7bb --- /dev/null +++ b/fa/code/src/apps/ch.5.6/redis/readme.md @@ -0,0 +1,10 @@ +## Setup for `ch.5.6` for Redis + +- Step 1) Install and run Redis +- Step 2) Launch the Redis server matching the DB constants. + + DB_PORT = "9191" + DB_URL = "127.0.0.1" + +- Step 3) Run `go get` to download and install the remote packages. +- Step 4) Execute the program with `go run main.go` diff --git a/fa/code/src/mymath/sqrt.go b/fa/code/src/mymath/sqrt.go new file mode 100644 index 00000000..6f089e05 --- /dev/null +++ b/fa/code/src/mymath/sqrt.go @@ -0,0 +1,12 @@ +// Example code for Chapter 1.2 from "Build Web Application with Golang" +// Purpose: Shows how to create a simple package called `mymath` +// This package must be imported from another go file to run. +package mymath + +func Sqrt(x float64) float64 { + z := 0.0 + for i := 0; i < 1000; i++ { + z -= (z*z - x) / (2 * x) + } + return z +} diff --git a/fa/images/1.1.cmd.png b/fa/images/1.1.cmd.png new file mode 100644 index 00000000..0df2504b Binary files /dev/null and b/fa/images/1.1.cmd.png differ diff --git a/fa/images/1.1.cmd.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.1.cmd.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..0df2504b Binary files /dev/null and b/fa/images/1.1.cmd.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.1.cmd.png~update the structure for gitbook b/fa/images/1.1.cmd.png~update the structure for gitbook new file mode 100644 index 00000000..0df2504b Binary files /dev/null and b/fa/images/1.1.cmd.png~update the structure for gitbook differ diff --git a/fa/images/1.1.linux.png b/fa/images/1.1.linux.png new file mode 100644 index 00000000..539563d9 Binary files /dev/null and b/fa/images/1.1.linux.png differ diff --git a/fa/images/1.1.linux.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.1.linux.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..45ffd924 Binary files /dev/null and b/fa/images/1.1.linux.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.1.linux.png~update the structure for gitbook b/fa/images/1.1.linux.png~update the structure for gitbook new file mode 100644 index 00000000..539563d9 Binary files /dev/null and b/fa/images/1.1.linux.png~update the structure for gitbook differ diff --git a/fa/images/1.1.mac.png b/fa/images/1.1.mac.png new file mode 100644 index 00000000..ad2ceed6 Binary files /dev/null and b/fa/images/1.1.mac.png differ diff --git a/fa/images/1.1.mac.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.1.mac.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..45ffd924 Binary files /dev/null and b/fa/images/1.1.mac.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.1.mac.png~update the structure for gitbook b/fa/images/1.1.mac.png~update the structure for gitbook new file mode 100644 index 00000000..ad2ceed6 Binary files /dev/null and b/fa/images/1.1.mac.png~update the structure for gitbook differ diff --git a/fa/images/1.3.go.png b/fa/images/1.3.go.png new file mode 100644 index 00000000..8155b2d5 Binary files /dev/null and b/fa/images/1.3.go.png differ diff --git a/fa/images/1.3.go.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.3.go.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..8155b2d5 Binary files /dev/null and b/fa/images/1.3.go.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.3.go.png~update the structure for gitbook b/fa/images/1.3.go.png~update the structure for gitbook new file mode 100644 index 00000000..8155b2d5 Binary files /dev/null and b/fa/images/1.3.go.png~update the structure for gitbook differ diff --git a/fa/images/1.4.eclipse1.png b/fa/images/1.4.eclipse1.png new file mode 100644 index 00000000..5b2f10d8 Binary files /dev/null and b/fa/images/1.4.eclipse1.png differ diff --git a/fa/images/1.4.eclipse1.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.eclipse1.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..5b2f10d8 Binary files /dev/null and b/fa/images/1.4.eclipse1.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.eclipse1.png~update the structure for gitbook b/fa/images/1.4.eclipse1.png~update the structure for gitbook new file mode 100644 index 00000000..5b2f10d8 Binary files /dev/null and b/fa/images/1.4.eclipse1.png~update the structure for gitbook differ diff --git a/fa/images/1.4.eclipse2.png b/fa/images/1.4.eclipse2.png new file mode 100644 index 00000000..55931f33 Binary files /dev/null and b/fa/images/1.4.eclipse2.png differ diff --git a/fa/images/1.4.eclipse2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.eclipse2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..55931f33 Binary files /dev/null and b/fa/images/1.4.eclipse2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.eclipse2.png~update the structure for gitbook b/fa/images/1.4.eclipse2.png~update the structure for gitbook new file mode 100644 index 00000000..55931f33 Binary files /dev/null and b/fa/images/1.4.eclipse2.png~update the structure for gitbook differ diff --git a/fa/images/1.4.eclipse3.png b/fa/images/1.4.eclipse3.png new file mode 100644 index 00000000..3c7bd634 Binary files /dev/null and b/fa/images/1.4.eclipse3.png differ diff --git a/fa/images/1.4.eclipse3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.eclipse3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..3c7bd634 Binary files /dev/null and b/fa/images/1.4.eclipse3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.eclipse3.png~update the structure for gitbook b/fa/images/1.4.eclipse3.png~update the structure for gitbook new file mode 100644 index 00000000..3c7bd634 Binary files /dev/null and b/fa/images/1.4.eclipse3.png~update the structure for gitbook differ diff --git a/fa/images/1.4.eclipse4.png b/fa/images/1.4.eclipse4.png new file mode 100644 index 00000000..d4ee77af Binary files /dev/null and b/fa/images/1.4.eclipse4.png differ diff --git a/fa/images/1.4.eclipse4.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.eclipse4.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..d4ee77af Binary files /dev/null and b/fa/images/1.4.eclipse4.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.eclipse4.png~update the structure for gitbook b/fa/images/1.4.eclipse4.png~update the structure for gitbook new file mode 100644 index 00000000..d4ee77af Binary files /dev/null and b/fa/images/1.4.eclipse4.png~update the structure for gitbook differ diff --git a/fa/images/1.4.eclipse5.png b/fa/images/1.4.eclipse5.png new file mode 100644 index 00000000..8a89555d Binary files /dev/null and b/fa/images/1.4.eclipse5.png differ diff --git a/fa/images/1.4.eclipse5.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.eclipse5.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..8a89555d Binary files /dev/null and b/fa/images/1.4.eclipse5.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.eclipse5.png~update the structure for gitbook b/fa/images/1.4.eclipse5.png~update the structure for gitbook new file mode 100644 index 00000000..8a89555d Binary files /dev/null and b/fa/images/1.4.eclipse5.png~update the structure for gitbook differ diff --git a/fa/images/1.4.eclipse6.png b/fa/images/1.4.eclipse6.png new file mode 100644 index 00000000..7771ec2e Binary files /dev/null and b/fa/images/1.4.eclipse6.png differ diff --git a/fa/images/1.4.eclipse6.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.eclipse6.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..7771ec2e Binary files /dev/null and b/fa/images/1.4.eclipse6.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.eclipse6.png~update the structure for gitbook b/fa/images/1.4.eclipse6.png~update the structure for gitbook new file mode 100644 index 00000000..7771ec2e Binary files /dev/null and b/fa/images/1.4.eclipse6.png~update the structure for gitbook differ diff --git a/fa/images/1.4.emacs.png b/fa/images/1.4.emacs.png new file mode 100644 index 00000000..3dd6845f Binary files /dev/null and b/fa/images/1.4.emacs.png differ diff --git a/fa/images/1.4.emacs.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.emacs.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..3dd6845f Binary files /dev/null and b/fa/images/1.4.emacs.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.emacs.png~update the structure for gitbook b/fa/images/1.4.emacs.png~update the structure for gitbook new file mode 100644 index 00000000..3dd6845f Binary files /dev/null and b/fa/images/1.4.emacs.png~update the structure for gitbook differ diff --git a/fa/images/1.4.idea1.png b/fa/images/1.4.idea1.png new file mode 100644 index 00000000..87d2e51e Binary files /dev/null and b/fa/images/1.4.idea1.png differ diff --git a/fa/images/1.4.idea1.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.idea1.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..87d2e51e Binary files /dev/null and b/fa/images/1.4.idea1.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.idea1.png~update the structure for gitbook b/fa/images/1.4.idea1.png~update the structure for gitbook new file mode 100644 index 00000000..87d2e51e Binary files /dev/null and b/fa/images/1.4.idea1.png~update the structure for gitbook differ diff --git a/fa/images/1.4.idea2.png b/fa/images/1.4.idea2.png new file mode 100644 index 00000000..8059b20f Binary files /dev/null and b/fa/images/1.4.idea2.png differ diff --git a/fa/images/1.4.idea2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.idea2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..8059b20f Binary files /dev/null and b/fa/images/1.4.idea2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.idea2.png~update the structure for gitbook b/fa/images/1.4.idea2.png~update the structure for gitbook new file mode 100644 index 00000000..8059b20f Binary files /dev/null and b/fa/images/1.4.idea2.png~update the structure for gitbook differ diff --git a/fa/images/1.4.idea3.png b/fa/images/1.4.idea3.png new file mode 100644 index 00000000..574e1d74 Binary files /dev/null and b/fa/images/1.4.idea3.png differ diff --git a/fa/images/1.4.idea3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.idea3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..574e1d74 Binary files /dev/null and b/fa/images/1.4.idea3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.idea3.png~update the structure for gitbook b/fa/images/1.4.idea3.png~update the structure for gitbook new file mode 100644 index 00000000..574e1d74 Binary files /dev/null and b/fa/images/1.4.idea3.png~update the structure for gitbook differ diff --git a/fa/images/1.4.idea4.png b/fa/images/1.4.idea4.png new file mode 100644 index 00000000..f6e5138d Binary files /dev/null and b/fa/images/1.4.idea4.png differ diff --git a/fa/images/1.4.idea4.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.idea4.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..f6e5138d Binary files /dev/null and b/fa/images/1.4.idea4.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.idea4.png~update the structure for gitbook b/fa/images/1.4.idea4.png~update the structure for gitbook new file mode 100644 index 00000000..f6e5138d Binary files /dev/null and b/fa/images/1.4.idea4.png~update the structure for gitbook differ diff --git a/fa/images/1.4.idea5.png b/fa/images/1.4.idea5.png new file mode 100644 index 00000000..7784a611 Binary files /dev/null and b/fa/images/1.4.idea5.png differ diff --git a/fa/images/1.4.idea5.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.idea5.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..7784a611 Binary files /dev/null and b/fa/images/1.4.idea5.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.idea5.png~update the structure for gitbook b/fa/images/1.4.idea5.png~update the structure for gitbook new file mode 100644 index 00000000..7784a611 Binary files /dev/null and b/fa/images/1.4.idea5.png~update the structure for gitbook differ diff --git a/fa/images/1.4.liteide.png b/fa/images/1.4.liteide.png new file mode 100644 index 00000000..f28d755e Binary files /dev/null and b/fa/images/1.4.liteide.png differ diff --git a/fa/images/1.4.liteide.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.liteide.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..f28d755e Binary files /dev/null and b/fa/images/1.4.liteide.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.liteide.png~update the structure for gitbook b/fa/images/1.4.liteide.png~update the structure for gitbook new file mode 100644 index 00000000..f28d755e Binary files /dev/null and b/fa/images/1.4.liteide.png~update the structure for gitbook differ diff --git a/fa/images/1.4.sublime1.png b/fa/images/1.4.sublime1.png new file mode 100644 index 00000000..60f2b3db Binary files /dev/null and b/fa/images/1.4.sublime1.png differ diff --git a/fa/images/1.4.sublime1.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.sublime1.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..60f2b3db Binary files /dev/null and b/fa/images/1.4.sublime1.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.sublime1.png~update the structure for gitbook b/fa/images/1.4.sublime1.png~update the structure for gitbook new file mode 100644 index 00000000..60f2b3db Binary files /dev/null and b/fa/images/1.4.sublime1.png~update the structure for gitbook differ diff --git a/fa/images/1.4.sublime2.png b/fa/images/1.4.sublime2.png new file mode 100644 index 00000000..a888636f Binary files /dev/null and b/fa/images/1.4.sublime2.png differ diff --git a/fa/images/1.4.sublime2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.sublime2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..a888636f Binary files /dev/null and b/fa/images/1.4.sublime2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.sublime2.png~update the structure for gitbook b/fa/images/1.4.sublime2.png~update the structure for gitbook new file mode 100644 index 00000000..a888636f Binary files /dev/null and b/fa/images/1.4.sublime2.png~update the structure for gitbook differ diff --git a/fa/images/1.4.sublime3.png b/fa/images/1.4.sublime3.png new file mode 100644 index 00000000..8b2eb3dc Binary files /dev/null and b/fa/images/1.4.sublime3.png differ diff --git a/fa/images/1.4.sublime3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.sublime3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..8b2eb3dc Binary files /dev/null and b/fa/images/1.4.sublime3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.sublime3.png~update the structure for gitbook b/fa/images/1.4.sublime3.png~update the structure for gitbook new file mode 100644 index 00000000..8b2eb3dc Binary files /dev/null and b/fa/images/1.4.sublime3.png~update the structure for gitbook differ diff --git a/fa/images/1.4.sublime4.png b/fa/images/1.4.sublime4.png new file mode 100644 index 00000000..b0fef624 Binary files /dev/null and b/fa/images/1.4.sublime4.png differ diff --git a/fa/images/1.4.sublime4.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.sublime4.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b0fef624 Binary files /dev/null and b/fa/images/1.4.sublime4.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.sublime4.png~update the structure for gitbook b/fa/images/1.4.sublime4.png~update the structure for gitbook new file mode 100644 index 00000000..b0fef624 Binary files /dev/null and b/fa/images/1.4.sublime4.png~update the structure for gitbook differ diff --git a/fa/images/1.4.vim.png b/fa/images/1.4.vim.png new file mode 100644 index 00000000..27a15c05 Binary files /dev/null and b/fa/images/1.4.vim.png differ diff --git a/fa/images/1.4.vim.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/1.4.vim.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..27a15c05 Binary files /dev/null and b/fa/images/1.4.vim.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/1.4.vim.png~update the structure for gitbook b/fa/images/1.4.vim.png~update the structure for gitbook new file mode 100644 index 00000000..27a15c05 Binary files /dev/null and b/fa/images/1.4.vim.png~update the structure for gitbook differ diff --git a/fa/images/13.1.flow.png b/fa/images/13.1.flow.png new file mode 100644 index 00000000..b9d6c2f3 Binary files /dev/null and b/fa/images/13.1.flow.png differ diff --git a/fa/images/13.1.gopath.png b/fa/images/13.1.gopath.png new file mode 100644 index 00000000..c948437a Binary files /dev/null and b/fa/images/13.1.gopath.png differ diff --git a/fa/images/13.1.gopath.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/13.1.gopath.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..c948437a Binary files /dev/null and b/fa/images/13.1.gopath.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/13.1.gopath.png~update the structure for gitbook b/fa/images/13.1.gopath.png~update the structure for gitbook new file mode 100644 index 00000000..c948437a Binary files /dev/null and b/fa/images/13.1.gopath.png~update the structure for gitbook differ diff --git a/fa/images/13.1.gopath2.png b/fa/images/13.1.gopath2.png new file mode 100644 index 00000000..450b4104 Binary files /dev/null and b/fa/images/13.1.gopath2.png differ diff --git a/fa/images/13.1.gopath2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/13.1.gopath2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..450b4104 Binary files /dev/null and b/fa/images/13.1.gopath2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/13.1.gopath2.png~update the structure for gitbook b/fa/images/13.1.gopath2.png~update the structure for gitbook new file mode 100644 index 00000000..450b4104 Binary files /dev/null and b/fa/images/13.1.gopath2.png~update the structure for gitbook differ diff --git a/fa/images/13.4.beego.png b/fa/images/13.4.beego.png new file mode 100644 index 00000000..96a9d274 Binary files /dev/null and b/fa/images/13.4.beego.png differ diff --git a/fa/images/13.4.beego.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/13.4.beego.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..96a9d274 Binary files /dev/null and b/fa/images/13.4.beego.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/13.4.beego.png~update the structure for gitbook b/fa/images/13.4.beego.png~update the structure for gitbook new file mode 100644 index 00000000..96a9d274 Binary files /dev/null and b/fa/images/13.4.beego.png~update the structure for gitbook differ diff --git a/fa/images/14.1.bootstrap.png b/fa/images/14.1.bootstrap.png new file mode 100644 index 00000000..13ab7f82 Binary files /dev/null and b/fa/images/14.1.bootstrap.png differ diff --git a/fa/images/14.1.bootstrap.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.1.bootstrap.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..13ab7f82 Binary files /dev/null and b/fa/images/14.1.bootstrap.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.1.bootstrap.png~update the structure for gitbook b/fa/images/14.1.bootstrap.png~update the structure for gitbook new file mode 100644 index 00000000..13ab7f82 Binary files /dev/null and b/fa/images/14.1.bootstrap.png~update the structure for gitbook differ diff --git a/fa/images/14.1.bootstrap2.png b/fa/images/14.1.bootstrap2.png new file mode 100644 index 00000000..753ffc79 Binary files /dev/null and b/fa/images/14.1.bootstrap2.png differ diff --git a/fa/images/14.1.bootstrap2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.1.bootstrap2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..753ffc79 Binary files /dev/null and b/fa/images/14.1.bootstrap2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.1.bootstrap2.png~update the structure for gitbook b/fa/images/14.1.bootstrap2.png~update the structure for gitbook new file mode 100644 index 00000000..753ffc79 Binary files /dev/null and b/fa/images/14.1.bootstrap2.png~update the structure for gitbook differ diff --git a/fa/images/14.1.bootstrap3.png b/fa/images/14.1.bootstrap3.png new file mode 100644 index 00000000..460b8183 Binary files /dev/null and b/fa/images/14.1.bootstrap3.png differ diff --git a/fa/images/14.1.bootstrap3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.1.bootstrap3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..460b8183 Binary files /dev/null and b/fa/images/14.1.bootstrap3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.1.bootstrap3.png~update the structure for gitbook b/fa/images/14.1.bootstrap3.png~update the structure for gitbook new file mode 100644 index 00000000..460b8183 Binary files /dev/null and b/fa/images/14.1.bootstrap3.png~update the structure for gitbook differ diff --git a/fa/images/14.4.github.png b/fa/images/14.4.github.png new file mode 100644 index 00000000..4da4c6f5 Binary files /dev/null and b/fa/images/14.4.github.png differ diff --git a/fa/images/14.4.github.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.4.github.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..4da4c6f5 Binary files /dev/null and b/fa/images/14.4.github.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.4.github.png~update the structure for gitbook b/fa/images/14.4.github.png~update the structure for gitbook new file mode 100644 index 00000000..4da4c6f5 Binary files /dev/null and b/fa/images/14.4.github.png~update the structure for gitbook differ diff --git a/fa/images/14.4.github2.png b/fa/images/14.4.github2.png new file mode 100644 index 00000000..c3ae04bf Binary files /dev/null and b/fa/images/14.4.github2.png differ diff --git a/fa/images/14.4.github2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.4.github2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..c3ae04bf Binary files /dev/null and b/fa/images/14.4.github2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.4.github2.png~update the structure for gitbook b/fa/images/14.4.github2.png~update the structure for gitbook new file mode 100644 index 00000000..c3ae04bf Binary files /dev/null and b/fa/images/14.4.github2.png~update the structure for gitbook differ diff --git a/fa/images/14.4.github3.png b/fa/images/14.4.github3.png new file mode 100644 index 00000000..e98768c3 Binary files /dev/null and b/fa/images/14.4.github3.png differ diff --git a/fa/images/14.4.github3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.4.github3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..e98768c3 Binary files /dev/null and b/fa/images/14.4.github3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.4.github3.png~update the structure for gitbook b/fa/images/14.4.github3.png~update the structure for gitbook new file mode 100644 index 00000000..e98768c3 Binary files /dev/null and b/fa/images/14.4.github3.png~update the structure for gitbook differ diff --git a/fa/images/14.6.pprof.png b/fa/images/14.6.pprof.png new file mode 100644 index 00000000..532f1a76 Binary files /dev/null and b/fa/images/14.6.pprof.png differ diff --git a/fa/images/14.6.pprof.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.6.pprof.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..532f1a76 Binary files /dev/null and b/fa/images/14.6.pprof.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.6.pprof.png~update the structure for gitbook b/fa/images/14.6.pprof.png~update the structure for gitbook new file mode 100644 index 00000000..532f1a76 Binary files /dev/null and b/fa/images/14.6.pprof.png~update the structure for gitbook differ diff --git a/fa/images/14.6.pprof2.png b/fa/images/14.6.pprof2.png new file mode 100644 index 00000000..610c93a4 Binary files /dev/null and b/fa/images/14.6.pprof2.png differ diff --git a/fa/images/14.6.pprof2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.6.pprof2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..610c93a4 Binary files /dev/null and b/fa/images/14.6.pprof2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.6.pprof2.png~update the structure for gitbook b/fa/images/14.6.pprof2.png~update the structure for gitbook new file mode 100644 index 00000000..610c93a4 Binary files /dev/null and b/fa/images/14.6.pprof2.png~update the structure for gitbook differ diff --git a/fa/images/14.6.pprof3.png b/fa/images/14.6.pprof3.png new file mode 100644 index 00000000..a3b9f7ba Binary files /dev/null and b/fa/images/14.6.pprof3.png differ diff --git a/fa/images/14.6.pprof3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/14.6.pprof3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..a3b9f7ba Binary files /dev/null and b/fa/images/14.6.pprof3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/14.6.pprof3.png~update the structure for gitbook b/fa/images/14.6.pprof3.png~update the structure for gitbook new file mode 100644 index 00000000..a3b9f7ba Binary files /dev/null and b/fa/images/14.6.pprof3.png~update the structure for gitbook differ diff --git a/fa/images/2.2.array.png b/fa/images/2.2.array.png new file mode 100644 index 00000000..5560023b Binary files /dev/null and b/fa/images/2.2.array.png differ diff --git a/fa/images/2.2.array.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.2.array.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..5560023b Binary files /dev/null and b/fa/images/2.2.array.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.2.array.png~update the structure for gitbook b/fa/images/2.2.array.png~update the structure for gitbook new file mode 100644 index 00000000..5560023b Binary files /dev/null and b/fa/images/2.2.array.png~update the structure for gitbook differ diff --git a/fa/images/2.2.basic.png b/fa/images/2.2.basic.png new file mode 100644 index 00000000..9bac6a0f Binary files /dev/null and b/fa/images/2.2.basic.png differ diff --git a/fa/images/2.2.basic.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.2.basic.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..9bac6a0f Binary files /dev/null and b/fa/images/2.2.basic.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.2.basic.png~update the structure for gitbook b/fa/images/2.2.basic.png~update the structure for gitbook new file mode 100644 index 00000000..9bac6a0f Binary files /dev/null and b/fa/images/2.2.basic.png~update the structure for gitbook differ diff --git a/fa/images/2.2.makenew.png b/fa/images/2.2.makenew.png new file mode 100644 index 00000000..00f74179 Binary files /dev/null and b/fa/images/2.2.makenew.png differ diff --git a/fa/images/2.2.makenew.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.2.makenew.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..00f74179 Binary files /dev/null and b/fa/images/2.2.makenew.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.2.makenew.png~update the structure for gitbook b/fa/images/2.2.makenew.png~update the structure for gitbook new file mode 100644 index 00000000..00f74179 Binary files /dev/null and b/fa/images/2.2.makenew.png~update the structure for gitbook differ diff --git a/fa/images/2.2.slice.png b/fa/images/2.2.slice.png new file mode 100644 index 00000000..119f2141 Binary files /dev/null and b/fa/images/2.2.slice.png differ diff --git a/fa/images/2.2.slice.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.2.slice.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..119f2141 Binary files /dev/null and b/fa/images/2.2.slice.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.2.slice.png~update the structure for gitbook b/fa/images/2.2.slice.png~update the structure for gitbook new file mode 100644 index 00000000..119f2141 Binary files /dev/null and b/fa/images/2.2.slice.png~update the structure for gitbook differ diff --git a/fa/images/2.2.slice2.png b/fa/images/2.2.slice2.png new file mode 100644 index 00000000..0729a1bf Binary files /dev/null and b/fa/images/2.2.slice2.png differ diff --git a/fa/images/2.2.slice2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.2.slice2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..0729a1bf Binary files /dev/null and b/fa/images/2.2.slice2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.2.slice2.png~update the structure for gitbook b/fa/images/2.2.slice2.png~update the structure for gitbook new file mode 100644 index 00000000..0729a1bf Binary files /dev/null and b/fa/images/2.2.slice2.png~update the structure for gitbook differ diff --git a/fa/images/2.3.init.png b/fa/images/2.3.init.png new file mode 100644 index 00000000..abe7cfad Binary files /dev/null and b/fa/images/2.3.init.png differ diff --git a/fa/images/2.3.init.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.3.init.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..abe7cfad Binary files /dev/null and b/fa/images/2.3.init.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.3.init.png~update the structure for gitbook b/fa/images/2.3.init.png~update the structure for gitbook new file mode 100644 index 00000000..abe7cfad Binary files /dev/null and b/fa/images/2.3.init.png~update the structure for gitbook differ diff --git a/fa/images/2.4.student_struct.png b/fa/images/2.4.student_struct.png new file mode 100644 index 00000000..7c4f87ac Binary files /dev/null and b/fa/images/2.4.student_struct.png differ diff --git a/fa/images/2.4.student_struct.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.4.student_struct.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..7c4f87ac Binary files /dev/null and b/fa/images/2.4.student_struct.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.4.student_struct.png~update the structure for gitbook b/fa/images/2.4.student_struct.png~update the structure for gitbook new file mode 100644 index 00000000..7c4f87ac Binary files /dev/null and b/fa/images/2.4.student_struct.png~update the structure for gitbook differ diff --git a/fa/images/2.5.rect_func_without_receiver.png b/fa/images/2.5.rect_func_without_receiver.png new file mode 100644 index 00000000..b4b571fd Binary files /dev/null and b/fa/images/2.5.rect_func_without_receiver.png differ diff --git a/fa/images/2.5.rect_func_without_receiver.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.5.rect_func_without_receiver.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b4b571fd Binary files /dev/null and b/fa/images/2.5.rect_func_without_receiver.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.5.rect_func_without_receiver.png~update the structure for gitbook b/fa/images/2.5.rect_func_without_receiver.png~update the structure for gitbook new file mode 100644 index 00000000..b4b571fd Binary files /dev/null and b/fa/images/2.5.rect_func_without_receiver.png~update the structure for gitbook differ diff --git a/fa/images/2.5.shapes_func_with_receiver_cp.png b/fa/images/2.5.shapes_func_with_receiver_cp.png new file mode 100644 index 00000000..2d26a01d Binary files /dev/null and b/fa/images/2.5.shapes_func_with_receiver_cp.png differ diff --git a/fa/images/2.5.shapes_func_with_receiver_cp.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.5.shapes_func_with_receiver_cp.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..2d26a01d Binary files /dev/null and b/fa/images/2.5.shapes_func_with_receiver_cp.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.5.shapes_func_with_receiver_cp.png~update the structure for gitbook b/fa/images/2.5.shapes_func_with_receiver_cp.png~update the structure for gitbook new file mode 100644 index 00000000..2d26a01d Binary files /dev/null and b/fa/images/2.5.shapes_func_with_receiver_cp.png~update the structure for gitbook differ diff --git a/fa/images/2.5.shapes_func_without_receiver.png b/fa/images/2.5.shapes_func_without_receiver.png new file mode 100644 index 00000000..112f56fc Binary files /dev/null and b/fa/images/2.5.shapes_func_without_receiver.png differ diff --git a/fa/images/2.5.shapes_func_without_receiver.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/2.5.shapes_func_without_receiver.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..112f56fc Binary files /dev/null and b/fa/images/2.5.shapes_func_without_receiver.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/2.5.shapes_func_without_receiver.png~update the structure for gitbook b/fa/images/2.5.shapes_func_without_receiver.png~update the structure for gitbook new file mode 100644 index 00000000..112f56fc Binary files /dev/null and b/fa/images/2.5.shapes_func_without_receiver.png~update the structure for gitbook differ diff --git a/fa/images/3.1.dns2.png b/fa/images/3.1.dns2.png new file mode 100644 index 00000000..f432edf3 Binary files /dev/null and b/fa/images/3.1.dns2.png differ diff --git a/fa/images/3.1.dns2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.1.dns2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..f432edf3 Binary files /dev/null and b/fa/images/3.1.dns2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.1.dns2.png~update the structure for gitbook b/fa/images/3.1.dns2.png~update the structure for gitbook new file mode 100644 index 00000000..f432edf3 Binary files /dev/null and b/fa/images/3.1.dns2.png~update the structure for gitbook differ diff --git a/fa/images/3.1.dns_hierachy.png b/fa/images/3.1.dns_hierachy.png new file mode 100644 index 00000000..8dfeb232 Binary files /dev/null and b/fa/images/3.1.dns_hierachy.png differ diff --git a/fa/images/3.1.dns_hierachy.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.1.dns_hierachy.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..8dfeb232 Binary files /dev/null and b/fa/images/3.1.dns_hierachy.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.1.dns_hierachy.png~update the structure for gitbook b/fa/images/3.1.dns_hierachy.png~update the structure for gitbook new file mode 100644 index 00000000..8dfeb232 Binary files /dev/null and b/fa/images/3.1.dns_hierachy.png~update the structure for gitbook differ diff --git a/fa/images/3.1.dns_inquery.png b/fa/images/3.1.dns_inquery.png new file mode 100644 index 00000000..b95d952e Binary files /dev/null and b/fa/images/3.1.dns_inquery.png differ diff --git a/fa/images/3.1.dns_inquery.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.1.dns_inquery.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b95d952e Binary files /dev/null and b/fa/images/3.1.dns_inquery.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.1.dns_inquery.png~update the structure for gitbook b/fa/images/3.1.dns_inquery.png~update the structure for gitbook new file mode 100644 index 00000000..b95d952e Binary files /dev/null and b/fa/images/3.1.dns_inquery.png~update the structure for gitbook differ diff --git a/fa/images/3.1.http.png b/fa/images/3.1.http.png new file mode 100644 index 00000000..25108bf3 Binary files /dev/null and b/fa/images/3.1.http.png differ diff --git a/fa/images/3.1.http.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.1.http.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..25108bf3 Binary files /dev/null and b/fa/images/3.1.http.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.1.http.png~update the structure for gitbook b/fa/images/3.1.http.png~update the structure for gitbook new file mode 100644 index 00000000..25108bf3 Binary files /dev/null and b/fa/images/3.1.http.png~update the structure for gitbook differ diff --git a/fa/images/3.1.httpPOST.png b/fa/images/3.1.httpPOST.png new file mode 100644 index 00000000..31d02020 Binary files /dev/null and b/fa/images/3.1.httpPOST.png differ diff --git a/fa/images/3.1.httpPOST.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.1.httpPOST.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..31d02020 Binary files /dev/null and b/fa/images/3.1.httpPOST.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.1.httpPOST.png~update the structure for gitbook b/fa/images/3.1.httpPOST.png~update the structure for gitbook new file mode 100644 index 00000000..31d02020 Binary files /dev/null and b/fa/images/3.1.httpPOST.png~update the structure for gitbook differ diff --git a/fa/images/3.1.response.png b/fa/images/3.1.response.png new file mode 100644 index 00000000..978de790 Binary files /dev/null and b/fa/images/3.1.response.png differ diff --git a/fa/images/3.1.response.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.1.response.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..978de790 Binary files /dev/null and b/fa/images/3.1.response.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.1.response.png~update the structure for gitbook b/fa/images/3.1.response.png~update the structure for gitbook new file mode 100644 index 00000000..978de790 Binary files /dev/null and b/fa/images/3.1.response.png~update the structure for gitbook differ diff --git a/fa/images/3.1.web.png b/fa/images/3.1.web.png new file mode 100644 index 00000000..5b98b5dc Binary files /dev/null and b/fa/images/3.1.web.png differ diff --git a/fa/images/3.1.web.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.1.web.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..5b98b5dc Binary files /dev/null and b/fa/images/3.1.web.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.1.web.png~update the structure for gitbook b/fa/images/3.1.web.png~update the structure for gitbook new file mode 100644 index 00000000..5b98b5dc Binary files /dev/null and b/fa/images/3.1.web.png~update the structure for gitbook differ diff --git a/fa/images/3.1.web2.png b/fa/images/3.1.web2.png new file mode 100644 index 00000000..a604c217 Binary files /dev/null and b/fa/images/3.1.web2.png differ diff --git a/fa/images/3.1.web2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.1.web2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..a604c217 Binary files /dev/null and b/fa/images/3.1.web2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.1.web2.png~update the structure for gitbook b/fa/images/3.1.web2.png~update the structure for gitbook new file mode 100644 index 00000000..a604c217 Binary files /dev/null and b/fa/images/3.1.web2.png~update the structure for gitbook differ diff --git a/fa/images/3.2.goweb.png b/fa/images/3.2.goweb.png new file mode 100644 index 00000000..d6a53829 Binary files /dev/null and b/fa/images/3.2.goweb.png differ diff --git a/fa/images/3.2.goweb.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.2.goweb.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..d6a53829 Binary files /dev/null and b/fa/images/3.2.goweb.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.2.goweb.png~update the structure for gitbook b/fa/images/3.2.goweb.png~update the structure for gitbook new file mode 100644 index 00000000..d6a53829 Binary files /dev/null and b/fa/images/3.2.goweb.png~update the structure for gitbook differ diff --git a/fa/images/3.3.http.png b/fa/images/3.3.http.png new file mode 100644 index 00000000..40137e33 Binary files /dev/null and b/fa/images/3.3.http.png differ diff --git a/fa/images/3.3.http.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.3.http.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..40137e33 Binary files /dev/null and b/fa/images/3.3.http.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.3.http.png~update the structure for gitbook b/fa/images/3.3.http.png~update the structure for gitbook new file mode 100644 index 00000000..40137e33 Binary files /dev/null and b/fa/images/3.3.http.png~update the structure for gitbook differ diff --git a/fa/images/3.3.illustrator.png b/fa/images/3.3.illustrator.png new file mode 100644 index 00000000..8159b8bb Binary files /dev/null and b/fa/images/3.3.illustrator.png differ diff --git a/fa/images/3.3.illustrator.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/3.3.illustrator.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..8159b8bb Binary files /dev/null and b/fa/images/3.3.illustrator.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/3.3.illustrator.png~update the structure for gitbook b/fa/images/3.3.illustrator.png~update the structure for gitbook new file mode 100644 index 00000000..8159b8bb Binary files /dev/null and b/fa/images/3.3.illustrator.png~update the structure for gitbook differ diff --git a/fa/images/4.1.login.png b/fa/images/4.1.login.png new file mode 100644 index 00000000..dfca39df Binary files /dev/null and b/fa/images/4.1.login.png differ diff --git a/fa/images/4.1.login.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/4.1.login.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..dfca39df Binary files /dev/null and b/fa/images/4.1.login.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/4.1.login.png~update the structure for gitbook b/fa/images/4.1.login.png~update the structure for gitbook new file mode 100644 index 00000000..dfca39df Binary files /dev/null and b/fa/images/4.1.login.png~update the structure for gitbook differ diff --git a/fa/images/4.1.slice.png b/fa/images/4.1.slice.png new file mode 100644 index 00000000..3405c147 Binary files /dev/null and b/fa/images/4.1.slice.png differ diff --git a/fa/images/4.1.slice.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/4.1.slice.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..3405c147 Binary files /dev/null and b/fa/images/4.1.slice.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/4.1.slice.png~update the structure for gitbook b/fa/images/4.1.slice.png~update the structure for gitbook new file mode 100644 index 00000000..3405c147 Binary files /dev/null and b/fa/images/4.1.slice.png~update the structure for gitbook differ diff --git a/fa/images/4.3.escape.png b/fa/images/4.3.escape.png new file mode 100644 index 00000000..76ce1245 Binary files /dev/null and b/fa/images/4.3.escape.png differ diff --git a/fa/images/4.3.escape.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/4.3.escape.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..76ce1245 Binary files /dev/null and b/fa/images/4.3.escape.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/4.3.escape.png~update the structure for gitbook b/fa/images/4.3.escape.png~update the structure for gitbook new file mode 100644 index 00000000..76ce1245 Binary files /dev/null and b/fa/images/4.3.escape.png~update the structure for gitbook differ diff --git a/fa/images/4.4.token.png b/fa/images/4.4.token.png new file mode 100644 index 00000000..b52cc1d1 Binary files /dev/null and b/fa/images/4.4.token.png differ diff --git a/fa/images/4.4.token.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/4.4.token.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b52cc1d1 Binary files /dev/null and b/fa/images/4.4.token.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/4.4.token.png~update the structure for gitbook b/fa/images/4.4.token.png~update the structure for gitbook new file mode 100644 index 00000000..b52cc1d1 Binary files /dev/null and b/fa/images/4.4.token.png~update the structure for gitbook differ diff --git a/fa/images/4.5.upload.png b/fa/images/4.5.upload.png new file mode 100644 index 00000000..e5766e38 Binary files /dev/null and b/fa/images/4.5.upload.png differ diff --git a/fa/images/4.5.upload.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/4.5.upload.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..e5766e38 Binary files /dev/null and b/fa/images/4.5.upload.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/4.5.upload.png~update the structure for gitbook b/fa/images/4.5.upload.png~update the structure for gitbook new file mode 100644 index 00000000..e5766e38 Binary files /dev/null and b/fa/images/4.5.upload.png~update the structure for gitbook differ diff --git a/fa/images/4.5.upload2.png b/fa/images/4.5.upload2.png new file mode 100644 index 00000000..06460446 Binary files /dev/null and b/fa/images/4.5.upload2.png differ diff --git a/fa/images/4.5.upload2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/4.5.upload2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..06460446 Binary files /dev/null and b/fa/images/4.5.upload2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/4.5.upload2.png~update the structure for gitbook b/fa/images/4.5.upload2.png~update the structure for gitbook new file mode 100644 index 00000000..06460446 Binary files /dev/null and b/fa/images/4.5.upload2.png~update the structure for gitbook differ diff --git a/fa/images/5.6.mongodb.png b/fa/images/5.6.mongodb.png new file mode 100644 index 00000000..6161fbe5 Binary files /dev/null and b/fa/images/5.6.mongodb.png differ diff --git a/fa/images/5.6.mongodb.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/5.6.mongodb.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..6161fbe5 Binary files /dev/null and b/fa/images/5.6.mongodb.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/5.6.mongodb.png~update the structure for gitbook b/fa/images/5.6.mongodb.png~update the structure for gitbook new file mode 100644 index 00000000..6161fbe5 Binary files /dev/null and b/fa/images/5.6.mongodb.png~update the structure for gitbook differ diff --git a/fa/images/6.1.cookie.png b/fa/images/6.1.cookie.png new file mode 100644 index 00000000..b94559cf Binary files /dev/null and b/fa/images/6.1.cookie.png differ diff --git a/fa/images/6.1.cookie.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/6.1.cookie.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b94559cf Binary files /dev/null and b/fa/images/6.1.cookie.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/6.1.cookie.png~update the structure for gitbook b/fa/images/6.1.cookie.png~update the structure for gitbook new file mode 100644 index 00000000..b94559cf Binary files /dev/null and b/fa/images/6.1.cookie.png~update the structure for gitbook differ diff --git a/fa/images/6.1.cookie2.png b/fa/images/6.1.cookie2.png new file mode 100644 index 00000000..8363a819 Binary files /dev/null and b/fa/images/6.1.cookie2.png differ diff --git a/fa/images/6.1.cookie2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/6.1.cookie2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..2888e392 Binary files /dev/null and b/fa/images/6.1.cookie2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/6.1.cookie2.png~update the structure for gitbook b/fa/images/6.1.cookie2.png~update the structure for gitbook new file mode 100644 index 00000000..2888e392 Binary files /dev/null and b/fa/images/6.1.cookie2.png~update the structure for gitbook differ diff --git a/fa/images/6.1.session.png b/fa/images/6.1.session.png new file mode 100644 index 00000000..a402af49 Binary files /dev/null and b/fa/images/6.1.session.png differ diff --git a/fa/images/6.1.session.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/6.1.session.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..f538b8f5 Binary files /dev/null and b/fa/images/6.1.session.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/6.1.session.png~update the structure for gitbook b/fa/images/6.1.session.png~update the structure for gitbook new file mode 100644 index 00000000..f538b8f5 Binary files /dev/null and b/fa/images/6.1.session.png~update the structure for gitbook differ diff --git a/fa/images/6.4.cookie.png b/fa/images/6.4.cookie.png new file mode 100644 index 00000000..0dad93f1 Binary files /dev/null and b/fa/images/6.4.cookie.png differ diff --git a/fa/images/6.4.cookie.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/6.4.cookie.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..0dad93f1 Binary files /dev/null and b/fa/images/6.4.cookie.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/6.4.cookie.png~update the structure for gitbook b/fa/images/6.4.cookie.png~update the structure for gitbook new file mode 100644 index 00000000..0dad93f1 Binary files /dev/null and b/fa/images/6.4.cookie.png~update the structure for gitbook differ diff --git a/fa/images/6.4.hijack.png b/fa/images/6.4.hijack.png new file mode 100644 index 00000000..5ab0753f Binary files /dev/null and b/fa/images/6.4.hijack.png differ diff --git a/fa/images/6.4.hijack.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/6.4.hijack.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..5ab0753f Binary files /dev/null and b/fa/images/6.4.hijack.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/6.4.hijack.png~update the structure for gitbook b/fa/images/6.4.hijack.png~update the structure for gitbook new file mode 100644 index 00000000..5ab0753f Binary files /dev/null and b/fa/images/6.4.hijack.png~update the structure for gitbook differ diff --git a/fa/images/6.4.hijacksuccess.png b/fa/images/6.4.hijacksuccess.png new file mode 100644 index 00000000..57f48d41 Binary files /dev/null and b/fa/images/6.4.hijacksuccess.png differ diff --git a/fa/images/6.4.hijacksuccess.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/6.4.hijacksuccess.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..57f48d41 Binary files /dev/null and b/fa/images/6.4.hijacksuccess.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/6.4.hijacksuccess.png~update the structure for gitbook b/fa/images/6.4.hijacksuccess.png~update the structure for gitbook new file mode 100644 index 00000000..57f48d41 Binary files /dev/null and b/fa/images/6.4.hijacksuccess.png~update the structure for gitbook differ diff --git a/fa/images/6.4.setcookie.png b/fa/images/6.4.setcookie.png new file mode 100644 index 00000000..dbb52170 Binary files /dev/null and b/fa/images/6.4.setcookie.png differ diff --git a/fa/images/6.4.setcookie.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/6.4.setcookie.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..dbb52170 Binary files /dev/null and b/fa/images/6.4.setcookie.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/6.4.setcookie.png~update the structure for gitbook b/fa/images/6.4.setcookie.png~update the structure for gitbook new file mode 100644 index 00000000..dbb52170 Binary files /dev/null and b/fa/images/6.4.setcookie.png~update the structure for gitbook differ diff --git a/fa/images/7.4.template.png b/fa/images/7.4.template.png new file mode 100644 index 00000000..195e24fb Binary files /dev/null and b/fa/images/7.4.template.png differ diff --git a/fa/images/7.4.template.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/7.4.template.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..195e24fb Binary files /dev/null and b/fa/images/7.4.template.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/7.4.template.png~update the structure for gitbook b/fa/images/7.4.template.png~update the structure for gitbook new file mode 100644 index 00000000..195e24fb Binary files /dev/null and b/fa/images/7.4.template.png~update the structure for gitbook differ diff --git a/fa/images/8.1.socket.png b/fa/images/8.1.socket.png new file mode 100644 index 00000000..93dd544d Binary files /dev/null and b/fa/images/8.1.socket.png differ diff --git a/fa/images/8.1.socket.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/8.1.socket.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..93dd544d Binary files /dev/null and b/fa/images/8.1.socket.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/8.1.socket.png~update the structure for gitbook b/fa/images/8.1.socket.png~update the structure for gitbook new file mode 100644 index 00000000..93dd544d Binary files /dev/null and b/fa/images/8.1.socket.png~update the structure for gitbook differ diff --git a/fa/images/8.2.websocket.png b/fa/images/8.2.websocket.png new file mode 100644 index 00000000..b293c653 Binary files /dev/null and b/fa/images/8.2.websocket.png differ diff --git a/fa/images/8.2.websocket.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/8.2.websocket.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b293c653 Binary files /dev/null and b/fa/images/8.2.websocket.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/8.2.websocket.png~update the structure for gitbook b/fa/images/8.2.websocket.png~update the structure for gitbook new file mode 100644 index 00000000..b293c653 Binary files /dev/null and b/fa/images/8.2.websocket.png~update the structure for gitbook differ diff --git a/fa/images/8.2.websocket2.png b/fa/images/8.2.websocket2.png new file mode 100644 index 00000000..b744c634 Binary files /dev/null and b/fa/images/8.2.websocket2.png differ diff --git a/fa/images/8.2.websocket2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/8.2.websocket2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b744c634 Binary files /dev/null and b/fa/images/8.2.websocket2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/8.2.websocket2.png~update the structure for gitbook b/fa/images/8.2.websocket2.png~update the structure for gitbook new file mode 100644 index 00000000..b744c634 Binary files /dev/null and b/fa/images/8.2.websocket2.png~update the structure for gitbook differ diff --git a/fa/images/8.2.websocket3.png b/fa/images/8.2.websocket3.png new file mode 100644 index 00000000..ee769c16 Binary files /dev/null and b/fa/images/8.2.websocket3.png differ diff --git a/fa/images/8.2.websocket3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/8.2.websocket3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..ee769c16 Binary files /dev/null and b/fa/images/8.2.websocket3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/8.2.websocket3.png~update the structure for gitbook b/fa/images/8.2.websocket3.png~update the structure for gitbook new file mode 100644 index 00000000..ee769c16 Binary files /dev/null and b/fa/images/8.2.websocket3.png~update the structure for gitbook differ diff --git a/fa/images/8.3.rest.png b/fa/images/8.3.rest.png new file mode 100644 index 00000000..0c1e5b54 Binary files /dev/null and b/fa/images/8.3.rest.png differ diff --git a/fa/images/8.3.rest.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/8.3.rest.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..0c1e5b54 Binary files /dev/null and b/fa/images/8.3.rest.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/8.3.rest.png~update the structure for gitbook b/fa/images/8.3.rest.png~update the structure for gitbook new file mode 100644 index 00000000..0c1e5b54 Binary files /dev/null and b/fa/images/8.3.rest.png~update the structure for gitbook differ diff --git a/fa/images/8.3.rest2.png b/fa/images/8.3.rest2.png new file mode 100644 index 00000000..b43c0804 Binary files /dev/null and b/fa/images/8.3.rest2.png differ diff --git a/fa/images/8.3.rest2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/8.3.rest2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b43c0804 Binary files /dev/null and b/fa/images/8.3.rest2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/8.3.rest2.png~update the structure for gitbook b/fa/images/8.3.rest2.png~update the structure for gitbook new file mode 100644 index 00000000..b43c0804 Binary files /dev/null and b/fa/images/8.3.rest2.png~update the structure for gitbook differ diff --git a/fa/images/8.3.rest3.png b/fa/images/8.3.rest3.png new file mode 100644 index 00000000..1f62b505 Binary files /dev/null and b/fa/images/8.3.rest3.png differ diff --git a/fa/images/8.3.rest3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/8.3.rest3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..1f62b505 Binary files /dev/null and b/fa/images/8.3.rest3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/8.3.rest3.png~update the structure for gitbook b/fa/images/8.3.rest3.png~update the structure for gitbook new file mode 100644 index 00000000..1f62b505 Binary files /dev/null and b/fa/images/8.3.rest3.png~update the structure for gitbook differ diff --git a/fa/images/8.4.rpc.png b/fa/images/8.4.rpc.png new file mode 100644 index 00000000..0b3fcfe2 Binary files /dev/null and b/fa/images/8.4.rpc.png differ diff --git a/fa/images/8.4.rpc.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/8.4.rpc.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..0b3fcfe2 Binary files /dev/null and b/fa/images/8.4.rpc.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/8.4.rpc.png~update the structure for gitbook b/fa/images/8.4.rpc.png~update the structure for gitbook new file mode 100644 index 00000000..0b3fcfe2 Binary files /dev/null and b/fa/images/8.4.rpc.png~update the structure for gitbook differ diff --git a/fa/images/9.1.csrf.png b/fa/images/9.1.csrf.png new file mode 100644 index 00000000..54d3a434 Binary files /dev/null and b/fa/images/9.1.csrf.png differ diff --git a/fa/images/9.1.csrf.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/9.1.csrf.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..54d3a434 Binary files /dev/null and b/fa/images/9.1.csrf.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/9.1.csrf.png~update the structure for gitbook b/fa/images/9.1.csrf.png~update the structure for gitbook new file mode 100644 index 00000000..54d3a434 Binary files /dev/null and b/fa/images/9.1.csrf.png~update the structure for gitbook differ diff --git a/fa/images/alipay.png b/fa/images/alipay.png new file mode 100644 index 00000000..2bac3531 Binary files /dev/null and b/fa/images/alipay.png differ diff --git a/fa/images/cover.png b/fa/images/cover.png new file mode 100644 index 00000000..22bfab44 Binary files /dev/null and b/fa/images/cover.png differ diff --git a/fa/images/cover.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/cover.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..22bfab44 Binary files /dev/null and b/fa/images/cover.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/cover.png~update the structure for gitbook b/fa/images/cover.png~update the structure for gitbook new file mode 100644 index 00000000..22bfab44 Binary files /dev/null and b/fa/images/cover.png~update the structure for gitbook differ diff --git a/fa/images/ebook.jpg b/fa/images/ebook.jpg new file mode 100644 index 00000000..b2f3710d Binary files /dev/null and b/fa/images/ebook.jpg differ diff --git a/fa/images/ebook.jpg~380a8ee74c41759d8189ad553423467994187253 b/fa/images/ebook.jpg~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..b2f3710d Binary files /dev/null and b/fa/images/ebook.jpg~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/ebook.jpg~update the structure for gitbook b/fa/images/ebook.jpg~update the structure for gitbook new file mode 100644 index 00000000..b2f3710d Binary files /dev/null and b/fa/images/ebook.jpg~update the structure for gitbook differ diff --git a/fa/images/navi1.png b/fa/images/navi1.png new file mode 100644 index 00000000..92a7669e Binary files /dev/null and b/fa/images/navi1.png differ diff --git a/fa/images/navi1.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi1.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..92a7669e Binary files /dev/null and b/fa/images/navi1.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi1.png~update the structure for gitbook b/fa/images/navi1.png~update the structure for gitbook new file mode 100644 index 00000000..92a7669e Binary files /dev/null and b/fa/images/navi1.png~update the structure for gitbook differ diff --git a/fa/images/navi10.png b/fa/images/navi10.png new file mode 100644 index 00000000..94935e27 Binary files /dev/null and b/fa/images/navi10.png differ diff --git a/fa/images/navi10.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi10.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..94935e27 Binary files /dev/null and b/fa/images/navi10.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi10.png~update the structure for gitbook b/fa/images/navi10.png~update the structure for gitbook new file mode 100644 index 00000000..94935e27 Binary files /dev/null and b/fa/images/navi10.png~update the structure for gitbook differ diff --git a/fa/images/navi11.png b/fa/images/navi11.png new file mode 100644 index 00000000..8eb93cb1 Binary files /dev/null and b/fa/images/navi11.png differ diff --git a/fa/images/navi11.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi11.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..8eb93cb1 Binary files /dev/null and b/fa/images/navi11.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi11.png~update the structure for gitbook b/fa/images/navi11.png~update the structure for gitbook new file mode 100644 index 00000000..8eb93cb1 Binary files /dev/null and b/fa/images/navi11.png~update the structure for gitbook differ diff --git a/fa/images/navi12.png b/fa/images/navi12.png new file mode 100644 index 00000000..5bdbadfa Binary files /dev/null and b/fa/images/navi12.png differ diff --git a/fa/images/navi12.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi12.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..5bdbadfa Binary files /dev/null and b/fa/images/navi12.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi12.png~update the structure for gitbook b/fa/images/navi12.png~update the structure for gitbook new file mode 100644 index 00000000..5bdbadfa Binary files /dev/null and b/fa/images/navi12.png~update the structure for gitbook differ diff --git a/fa/images/navi13.png b/fa/images/navi13.png new file mode 100644 index 00000000..c797033b Binary files /dev/null and b/fa/images/navi13.png differ diff --git a/fa/images/navi13.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi13.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..c797033b Binary files /dev/null and b/fa/images/navi13.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi13.png~update the structure for gitbook b/fa/images/navi13.png~update the structure for gitbook new file mode 100644 index 00000000..c797033b Binary files /dev/null and b/fa/images/navi13.png~update the structure for gitbook differ diff --git a/fa/images/navi14.png b/fa/images/navi14.png new file mode 100644 index 00000000..3d9d38cc Binary files /dev/null and b/fa/images/navi14.png differ diff --git a/fa/images/navi14.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi14.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..3d9d38cc Binary files /dev/null and b/fa/images/navi14.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi14.png~update the structure for gitbook b/fa/images/navi14.png~update the structure for gitbook new file mode 100644 index 00000000..3d9d38cc Binary files /dev/null and b/fa/images/navi14.png~update the structure for gitbook differ diff --git a/fa/images/navi2.png b/fa/images/navi2.png new file mode 100644 index 00000000..d18526ac Binary files /dev/null and b/fa/images/navi2.png differ diff --git a/fa/images/navi2.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi2.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..d18526ac Binary files /dev/null and b/fa/images/navi2.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi2.png~update the structure for gitbook b/fa/images/navi2.png~update the structure for gitbook new file mode 100644 index 00000000..d18526ac Binary files /dev/null and b/fa/images/navi2.png~update the structure for gitbook differ diff --git a/fa/images/navi3.png b/fa/images/navi3.png new file mode 100644 index 00000000..23495893 Binary files /dev/null and b/fa/images/navi3.png differ diff --git a/fa/images/navi3.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi3.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..23495893 Binary files /dev/null and b/fa/images/navi3.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi3.png~update the structure for gitbook b/fa/images/navi3.png~update the structure for gitbook new file mode 100644 index 00000000..23495893 Binary files /dev/null and b/fa/images/navi3.png~update the structure for gitbook differ diff --git a/fa/images/navi4.png b/fa/images/navi4.png new file mode 100644 index 00000000..1b4df73a Binary files /dev/null and b/fa/images/navi4.png differ diff --git a/fa/images/navi4.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi4.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..1b4df73a Binary files /dev/null and b/fa/images/navi4.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi4.png~update the structure for gitbook b/fa/images/navi4.png~update the structure for gitbook new file mode 100644 index 00000000..1b4df73a Binary files /dev/null and b/fa/images/navi4.png~update the structure for gitbook differ diff --git a/fa/images/navi5.png b/fa/images/navi5.png new file mode 100644 index 00000000..55788152 Binary files /dev/null and b/fa/images/navi5.png differ diff --git a/fa/images/navi5.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi5.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..55788152 Binary files /dev/null and b/fa/images/navi5.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi5.png~update the structure for gitbook b/fa/images/navi5.png~update the structure for gitbook new file mode 100644 index 00000000..55788152 Binary files /dev/null and b/fa/images/navi5.png~update the structure for gitbook differ diff --git a/fa/images/navi6.png b/fa/images/navi6.png new file mode 100644 index 00000000..74cab817 Binary files /dev/null and b/fa/images/navi6.png differ diff --git a/fa/images/navi6.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi6.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..74cab817 Binary files /dev/null and b/fa/images/navi6.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi6.png~update the structure for gitbook b/fa/images/navi6.png~update the structure for gitbook new file mode 100644 index 00000000..74cab817 Binary files /dev/null and b/fa/images/navi6.png~update the structure for gitbook differ diff --git a/fa/images/navi7.png b/fa/images/navi7.png new file mode 100644 index 00000000..2e1c974e Binary files /dev/null and b/fa/images/navi7.png differ diff --git a/fa/images/navi7.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi7.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..2e1c974e Binary files /dev/null and b/fa/images/navi7.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi7.png~update the structure for gitbook b/fa/images/navi7.png~update the structure for gitbook new file mode 100644 index 00000000..2e1c974e Binary files /dev/null and b/fa/images/navi7.png~update the structure for gitbook differ diff --git a/fa/images/navi8.png b/fa/images/navi8.png new file mode 100644 index 00000000..7a52d84e Binary files /dev/null and b/fa/images/navi8.png differ diff --git a/fa/images/navi8.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi8.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..7a52d84e Binary files /dev/null and b/fa/images/navi8.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi8.png~update the structure for gitbook b/fa/images/navi8.png~update the structure for gitbook new file mode 100644 index 00000000..7a52d84e Binary files /dev/null and b/fa/images/navi8.png~update the structure for gitbook differ diff --git a/fa/images/navi9.png b/fa/images/navi9.png new file mode 100644 index 00000000..7692e113 Binary files /dev/null and b/fa/images/navi9.png differ diff --git a/fa/images/navi9.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/navi9.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..7692e113 Binary files /dev/null and b/fa/images/navi9.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/navi9.png~update the structure for gitbook b/fa/images/navi9.png~update the structure for gitbook new file mode 100644 index 00000000..7692e113 Binary files /dev/null and b/fa/images/navi9.png~update the structure for gitbook differ diff --git a/fa/images/polling.png b/fa/images/polling.png new file mode 100644 index 00000000..8bd128ec Binary files /dev/null and b/fa/images/polling.png differ diff --git a/fa/images/polling.png~380a8ee74c41759d8189ad553423467994187253 b/fa/images/polling.png~380a8ee74c41759d8189ad553423467994187253 new file mode 100644 index 00000000..8bd128ec Binary files /dev/null and b/fa/images/polling.png~380a8ee74c41759d8189ad553423467994187253 differ diff --git a/fa/images/polling.png~update the structure for gitbook b/fa/images/polling.png~update the structure for gitbook new file mode 100644 index 00000000..8bd128ec Binary files /dev/null and b/fa/images/polling.png~update the structure for gitbook differ diff --git a/fa/preface.md b/fa/preface.md new file mode 100644 index 00000000..e604fbc9 --- /dev/null +++ b/fa/preface.md @@ -0,0 +1,100 @@ +
+ +- 1.[پیکربندی محیط Go](01.0.md) + - 1.1. [نصب](01.1.md) + - 1.2. [تنظیم $GOPATH و فضای کاری](01.2.md) + - 1.3. [دستورات Go](01.3.md) + - 1.4. [ابزارهای توسعه ی Go](01.4.md) + - 1.5. [خلاصه](01.5.md) +- 2.[دانش اولیه از Go](02.0.md) + - 2.1. ["سلام، Go"](02.1.md) + - 2.2. [دستورات پایه ای در Go](02.2.md) + - 2.3. [عبارات کنترلی و توابع](02.3.md) + - 2.4. [ساختار یا struct](02.4.md) + - 2.5. [شیء گرایی](02.5.md) + - 2.6. [اینترفیس](02.6.md) + - 2.7. [برنامه نویسی همروند](02.7.md) + - 2.8. [خلاصه](02.8.md) +- 3.[پایه و اساس وب](03.0.md) + - 3.1. [اصول کار در وب](03.1.md) + - 3.2. [ایجاد یک وب سرور ساده](03.2.md) + - 3.3. [چگونگی کارکرد Go در وب](03.3.md) + - 3.4. [آشنایی با پکیج های http در Go](03.4.md) + - 3.5. [خلاصه](03.5.md) +- 4.[فرم اطلاعات کاربر](04.0.md) + - 4.1. [پردازش ورودی ها](04.1.md) + - 4.2. [بررسی و تایید ورودی ها](04.2.md) + - 4.3. [تزریق اسکریپت از طریق وبگاه](04.3.md) + - 4.4. [اطلاعات تکراری](04.4.md) + - 4.5. [آپلود فایل](04.5.md) + - 4.6. [خلاصه](04.6.md) +- 5.[پایگاه داده](05.0.md) + - 5.1. [اینترفیس database/sql](05.1.md) + - 5.2. [MySQL](05.2.md) + - 5.3. [SQLite](05.3.md) + - 5.4. [PostgreSQL](05.4.md) + - 5.5. [نحوه کار با ORM با استفاده از beedb](05.5.md) + - 5.6. [پایگاه داده NoSQL](05.6.md) + - 5.7. [خلاصه](05.7.md) +- 6.[ذخیره داده و نشست](06.0.md) + - 6.1. [نشست و کوکی ها](06.1.md) + - 6.2. [نحوه استفاده از نشست در Go](06.2.md) + - 6.3. [ذخیره نشست](06.3.md) + - 6.4. [جلوگیری از سرقت نشست](06.4.md) + - 6.5. [خلاصه](06.5.md) +- 7.[فایل های متنی](07.0.md) + - 7.1. [XML](07.1.md) + - 7.2. [JSON](07.2.md) + - 7.3. [Regexp](07.3.md) + - 7.4. [استفاده از تمپلیت در Go](07.4.md) + - 7.5. [فایل ها](07.5.md) + - 7.6. [رشته ها](07.6.md) + - 7.7. [خلاصه](07.7.md) +- 8.[سرویس های وب](08.0.md) + - 8.1. [سوکت](08.1.md) + - 8.2. [وب سوکت](08.2.md) + - 8.3. [REST](08.3.md) + - 8.4. [RPC](08.4.md) + - 8.5. [خلاصه](08.5.md) +- 9.[امنیت و رمزنگاری](09.0.md) + - 9.1. [حملات CSRF](09.1.md) + - 9.2. [فیلتر کردن ورودی ها](09.2.md) + - 9.3. [حملات XSS](09.3.md) + - 9.4. [تزریق SQL](09.4.md) + - 9.5. [ذخیره رمز عبور](09.5.md) + - 9.6. [رمزنگاری و رمزگشایی داده ها](09.6.md) + - 9.7. [خلاصه](09.7.md) +- 10.[پشتیبانی از چند زبان و بومی سازی](10.0.md) + - 10.1 [منطقه زمانی](10.1.md) + - 10.2 [منابع محلی](10.2.md) + - 10.3 [سایت های بین المللی](10.3.md) + - 10.4 [خلاصه](10.4.md) +- 11.[کنترل خطا، دیباگ کردن و آزمون](11.0.md) + - 11.1. [کنترل خطا](11.1.md) + - 11.2. [دیباگ کردن با استفاده از GDB](11.2.md) + - 11.3. [نوشتن آزمون های مختلف](11.3.md) + - 11.4. [خلاصه](11.4.md) +- 12.[نصب و نگهداری](12.0.md) + - 12.1. [گزارشات](12.1.md) + - 12.2. [خطاها و کرش کردن](12.2.md) + - 12.3. [نصب و اجرا](12.3.md) + - 12.4. [پشتیبانی و بازیابی اطلاعات](12.4.md) + - 12.5. [خلاصه](12.5.md) +- 13.[ایجاد یک فریمورک وب](13.0.md) + - 13.1. [طراحی پروژه](13.1.md) + - 13.2. [مسیریابی سفارشی شده](13.2.md) + - 13.3. [طراحی کنترلرها](13.3.md) + - 13.4. [گزارشات و پیکربندی](13.4.md) + - 13.5. [افزودن، حذف و ویرایش پست های بلاگ](13.5.md) + - 13.6. [خلاصه](13.6.md) +- 14.[توسعه ی یک فریمورک وب](14.0.md) + - 14.1. [فایل های ایستا](14.1.md) + - 14.2. [نشست](14.2.md) + - 14.3. [فرم](14.3.md) + - 14.4. [تایید اعتبار کاربر](14.4.md) + - 14.5. [پشتیبانی از چند زبان](14.5.md) + - 14.6. [ابزار نظارت عملکرد pprof](14.6.md) + - 14.7. [خلاصه](14.7.md) +- پیوست الف [منابع](ref.md) + +
\ No newline at end of file diff --git a/fa/ref.md b/fa/ref.md new file mode 100644 index 00000000..1e18acf3 --- /dev/null +++ b/fa/ref.md @@ -0,0 +1,14 @@ +# پیوست الف، منابع + +این کتاب، خلاصه ای از تجربیات شخصی من در زمینه برنامه نویسی Go می باشد، با این حال ممکن است بعضی مطالب از سایت ها یا بلاگ های دیگر در این زمینه مطرح شده باشند. با تشکر از همه آن ها! + +1. [golang blog](http://blog.golang.org) +2. [Russ Cox blog](http://research.swtch.com/) +3. [go book](http://go-book.appsp0t.com/) +4. [golangtutorials](http://golangtutorials.blogspot.com) +5. [轩脉刃de刀光剑影](http://www.cnblogs.com/yjf512/) +6. [Go Programming Language](http://golang.org/doc/) +7. [Network programming with Go](http://jan.newmarch.name/go/) +8. [setup-the-rails-application-for-internationalization](http://guides.rubyonrails.org/i18n.html#setup-the-rails-application-for-internationalization) +9. [The Cross-Site Scripting (XSS) FAQ](http://www.cgisecurity.com/xss-faq.html) +10. [Network programming with Go](http://jan.newmarch.name/go) \ No newline at end of file diff --git a/fa/working/01.2.md b/fa/working/01.2.md new file mode 100644 index 00000000..925a4229 --- /dev/null +++ b/fa/working/01.2.md @@ -0,0 +1,156 @@ +# 1.2 $GOPATH و فضای کاری + +## $GOPATH + +Go با معرفی دایرکتوری `$GOPATH` روش منحصر به فردی برای مدیریت فایل های حاوی کد دارد. در این مسیر تمام کدهای مرتبط با go در سیستم شما قرار گرفته است. توجه داشته باشید که این دایرکتوری با متغیر محیطی `$GOROOT`، که مشخص می‌کند go در چه مسیری نصب شده است، تفاوت دارد. قبل از اینکه از این زبان برای برنامه‌نویسی استفاده کنیم باید متغیر `$GOPATH` را تعریف کنیم. در سیستم‌های شبه یونیکس (*nix) فایلی به نام ‍‍`.profile` وجود دارد که باید دستور زیر را به انتهای این فایل اضافه کنیم. مفهوم استفاده از gopath یک مفهوم جدید محسوب می شود که طی آن، هر کد go را می توان در هر زمان و بدون هیچ گونه ابهامی لینک نمود. + +در ورژن go 1.8 به بعد، اگر متغیر محیطی GOPATH تنظیم نشود، یک مقدار پیش فرض برای آن در نظر گرفته می شود که در یونیکس مقدار `$HOME/go` و در ویندوز مقدار `%USERPROFILE%/go` را دارد. + +در سیستم‌های شبه یونیکسی، این متغیر را می‌توان به صورت زیر مورد استفاده قرار داد: + export GOPATH=${HOME}/mygo + +در ویندوز، ابتدا باید یک متغیر محیطی به نام GOPATH ایجاد کنید، که با مقدار `c:\mygo` مقداردهی شده باشد. ( ***این مقدار بستگی به این دارد که فضای کاری شما در کجا قرار گرفته باشد*** ) + +طبیعتا مشکلی ندارد که در فضای کاری شما، بیشتر از یک مقدار برای `$GOPATH` در نظر گرفته شود، فقط توجه داشته باشید که با استفاده از `:` این مقادیر را از هم مجزا کنید (در ویندوز باید از `;` استفاده کنید). در این حالت، دستور `go get` محتوای اولین مسیر شما را در `$GOPATH` قرار می دهد. معمولا توصیه می‌شود که از نصب ورژن‌های متعدد Go خودداری شود. در برترین حالت ممکن است فولدری با نام پروژه خود در مسیر `$GOPATH` ایجاد کنید، که باعث می‌شود همه چیز به هم بریزد. چون وقتی در مسیر `$GOPATH` پوشه ای ساخته می شود، آن پوشه را به عنوان یک پکیج/بسته می شناسد. بنابراین وقتی از دستور `go get` استفاده می‌کنید، دنبال بسته ای هم نام با فولدر شما می‌گردد و طبیعتا آن را پیدا نمی‌کند. پس لطفا از قراردادهای تعریف شده برای برنامه‌نویسی پیروی کنید چون حتما برای تعریف هر یک از آن ها دلیلی وجود داشته است. + +در `$GOPATH`، شما باید سه فولدر به صورت زیر داشته باشید: + +- `src` برای سورس فایل‌هایی که پسوند .go، .c، .g، .s دارند. +- `pkg` برای فایل‌های کامپایل شده ای که پسوند .a دارند. +- `bin` برای فایل‌های اجرایی. + +در این کتاب، ما از `mygo` به عنوان تنها مقداری که در متغیر `$GOPATH` قرار گرفته استفاده می کنیم. + +## دایرکتوری بسته‌ها + +برای ایجاد سورس فایل‌ها و فولدرهای خود از مسیری مانند `$GOPATH/src/mymath/sqrt.go` استفاده کنید به طوری که `mymath` در واقع نام بسته شما محسوب می‌شود. ( ***شما ممکن است نام بسته خود را `mymath` بگذارید و در عین حال دقیقا همین نام را برای پوشه یا فایل‌های بسته در نظر بگیرید*** ) + +هر زمان که بسته ای ایجاد می‌کنید، باید پوشه‌ای در مسیر `src` برای این پکیج در نظر بگیرید، که البته توجه داشته باشید پکیج `main` یک استثناء محسوب می‌شود، چون ساخت پوشه‌ای برای `main` در واقع امری اختیاری است و اجباری ندارد. معمولا نام پوشه‌ها هم‌نام با نام بسته‌ای در نظر گرفته می‌شود که می‌خواهید از آن استفاده کنید. همچنین در صورت لزوم می‌توانید از دایرکتوری‌های چندسطحی استفاده کنید. برای مثال، اگر دایرکتوری `$GOPATH/src/github.com/astaxie/beedb` را ایجاد کرده‌اید، آن‌گاه مسیر بسته‌ی شما به صورت `github.com/astaxie/beedb` خواهد بود. نام بسته درواقع آخرین دایرکتوری در این مسیر می‌باشد که در این مثال `beedb` است. + +دستورات زیر را اجرا کنید. + + cd $GOPATH/src + mkdir mymath + +یک فایل جدید با نام `sqrt.go` ایجاد کرده و متن زیر را در این فایل قرار دهید. + +```Go +// Source code of $GOPATH/src/mymath/sqrt.go +package mymath + +func Sqrt(x float64) float64 { + z := 0.0 + for i := 0; i < 1000; i++ { + z -= (z*z - x) / (2 * x) + } + return z +} +``` +بدین ترتیب دایرکتوری بسته‌ی من ایجاد شده و کدهای مرتبط با آن هم بررسی کردیم. توصیه می‌کنیم که از همان نامی که برای بسته استفاده می‌کنید برای دایرکتوری مرتبط با آن استفاده کنید، به طوری که دایرکتوری شما تمام سورس فایل‌های مربوط به آن بسته را در خود دارد. + +## کامپایل بسته‌ها + +همان‌طور که در بالا عنوان شد، بسته‌ای را ایجاد کردیم. اما سوال اینجاست که چطور این بسته را برای کارهای عملی کامپایل کنیم؟ برای این کار دو روش زیر وجود دارند: + +1. به مسیر پکیج رفته و دستور `go install` را اجرا کنید. +2. دستور فوق را به همراه نام فایل اجرا کنید، مثلا `go install mymath`. + +بعد از اینکه کامپایل انجام شد، می توان به مسیر زیر رفت و تغییرات را مشاهده کرد. + + cd $GOPATH/pkg/${GOOS}_${GOARCH} + // فایل زیر بعد از کامپایل ایجاد شده است + mymath.a + +فایل که پسوند `.a` دارد، در واقع همان فایل باینری مربوط به بسته‌ی ما می‌باشد. چطور از این فایل استفاده کنیم؟ + +به نظر می‌رسد که برای استفاده از این فایل باید یک اپلیکیشن ایجاد کنیم. + +برای این کار یک پکیج اپلیکیشن با نام `mathapp` ایجاد کنید. + + cd $GOPATH/src + mkdir mathapp + cd mathapp + vim main.go + +در فایل main.go دستورات زیر را قرار دهید. + +```Go + +//$GOPATH/src/mathapp/main.go source code. +package main + +import ( + "mymath" + "fmt" +) + +func main() { + fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) +} +``` + +برای کامپایل این برنامه، باید به مسیر این بسته یعنی `$GOPATH/src/mathapp` رفته و دستور `go install` را اجرا کنید. بعد از کامپایل، یک فایل اجرایی با نام `mathapp` در دایرکتوری `$GOPATH/bin/` ایجاد می‌شود. برای اجرای این برنامه، از دستور `./mathapp` استفاده کنید. بعد از اجرای این دستور، عبارت زیر در ترمینال شما نمایش داده می‌شود. + + Hello world. Sqrt(2) = 1.414213562373095 + +## نصب بسته‌های ریموت + +Go has a tool for installing remote packages, which is a command called `go get`. It supports most open source communities, including Github, Google Code, BitBucket, and Launchpad. + + go get github.com/astaxie/beedb + +You can use `go get -u …` to update your remote packages and it will automatically install all the dependent packages as well. + +This tool will use different version control tools for different open source platforms. For example, `git` for Github and `hg` for Google Code. Therefore, you have to install these version control tools before you use `go get`. + +After executing the above commands, the directory structure should look like following. + + $GOPATH + src + |-github.com + |-astaxie + |-beedb + pkg + |--${GOOS}_${GOARCH} + |-github.com + |-astaxie + |-beedb.a + +Actually, `go get` clones source code to the `$GOPATH/src` of the local file system, then executes `go install`. + +You can use remote packages in the same way that we use local packages. +```Go +import "github.com/astaxie/beedb" +``` +## ساختار کامل دایرکتوری + +If you've followed all of the above steps, your directory structure should now look like the following. + + bin/ + mathapp + pkg/ + ${GOOS}_${GOARCH}, such as darwin_amd64, linux_amd64 + mymath.a + github.com/ + astaxie/ + beedb.a + src/ + mathapp + main.go + mymath/ + sqrt.go + github.com/ + astaxie/ + beedb/ + beedb.go + util.go + +Now you are able to see the directory structure clearly; `bin` contains executable files, `pkg` contains compiled files and `src` contains package source files. + +(The format of environment variables in Windows is `%GOPATH%`, however this book mainly follows the Unix-style, so Windows users need to replace these yourself.) + +## لینک‌ها + +- [فهرست مطالب](preface.md) +- بخش قبلی: [نصب](01.1.md) +- بخش بعدی: [دستورات Go](01.3.md) diff --git a/fa/working/01.3.md b/fa/working/01.3.md new file mode 100644 index 00000000..d8e7beee --- /dev/null +++ b/fa/working/01.3.md @@ -0,0 +1,106 @@ +# 1.3 Go commands + +## Go commands + +The Go language comes with a complete set of command operation tools. You can execute the `go` command on the terminal to see them: + +![](images/1.3.go.png?raw=true) + +Figure 1.3 Go command displays detailed information + +These are all useful for us. Let's see how to use some of them. + +## go build + +This command is for compiling tests. It will compile packages and dependencies if it's necessary. + +- If the package is not the `main` package such as `mymath` in section 1.2, nothing will be generated after you execute `go build`. If you need the package file `.a` in `$GOPATH/pkg`, use `go install` instead. +- If the package is the `main` package, it will generate an executable file in the same folder. If you want the file to be generated in `$GOPATH/bin`, use `go install` or `go build -o ${PATH_HERE}/a.exe.` +- If there are many files in the folder, but you just want to compile one of them, you should append the file name after `go build`. For example, `go build a.go`. `go build` will compile all the files in the folder. +- You can also assign the name of the file that will be generated. For instance, in the `mathapp` project (in section 1.2), using `go build -o astaxie.exe` will generate `astaxie.exe` instead of `mathapp.exe`. The default name is your folder name (non-main package) or the first source file name (main package). + +(According to [The Go Programming Language Specification](https://golang.org/ref/spec), package names should be the name after the word `package` in the first line of your source files. It doesn't have to be the same as the folder name, and the executable file name will be your folder name by default.) + +- `go build` ignores files whose names start with `_` or `.`. +- If you want to have different source files for every operating system, you can name files with the system name as a suffix. Suppose there are some source files for loading arrays. They could be named as follows: + + array_linux.go | array_darwin.go | array_windows.go | array_freebsd.go + +`go build` chooses the one that's associated with your operating system. For example, it only compiles array_linux.go in Linux systems, and ignores all the others. + +## go clean + +This command is for cleaning files that are generated by compilers, including the following files: + + _obj/ // old directory of object, left by Makefiles + _test/ // old directory of test, left by Makefiles + _testmain.go // old directory of gotest, left by Makefiles + test.out // old directory of test, left by Makefiles + build.out // old directory of test, left by Makefiles + *.[568ao] // object files, left by Makefiles + + DIR(.exe) // generated by go build + DIR.test(.exe) // generated by go test -c + MAINFILE(.exe) // generated by go build MAINFILE.go + +I usually use this command to clean up my files before I upload my project to Github. These are useful for local tests, but useless for version control. + +## go fmt and gofmt + +The people who are working with C/C++ should know that people are always arguing about which code style is better: K&R-style or ANSI-style. However in Go, there is only one code style which is enforced. For example, left braces must only be inserted at the end of lines, and they cannot be on their own lines, otherwise you will get compile errors! Fortunately, you don't have to remember these rules. `go fmt` does this job for you. Just execute the command `go fmt .go` in terminal. I don't use this command very much because IDEs usually execute this command automatically when you save source files. I will talk more about IDEs in the next section. + +`go fmt` is just an alias, which runs the command 'gofmt -l -w' on the packages named by the import paths. + +We usually use `gofmt -w` instead of `go fmt`. The latter will not rewrite your source files after formatting code. `gofmt -w src` formats the whole project. + +## go get + +This command is for getting remote packages. So far, it supports BitBucket, Github, Google Code and Launchpad. There are actually two things that happen after we execute this command. The first thing is that Go downloads the source code, then executes `go install`. Before you use this command, make sure you have installed all of the related tools. + + BitBucket (Mercurial Git) + Github (git) + Google Code (Git, Mercurial, Subversion) + Launchpad (Bazaar) + +In order to use this command, you have to install these tools correctly. Don't forget to update the `$PATH` variable. By the way, it also supports customized domain names. Use `go help importpath` for more details about this. + +## go install + +This command compiles all packages and generates files, then moves them to `$GOPATH/pkg` or `$GOPATH/bin`. + +## go test + +This command loads all files whose name include `*_test.go` and generates test files, then prints information that looks like the following. + + ok archive/tar 0.011s + FAIL archive/zip 0.022s + ok compress/gzip 0.033s + ... + +It tests all your test files by default. Use command `go help testflag` for more details. + +## godoc + +Many people say that we don't need any third-party documentation for programming in Go (actually I've made a [CHM](https://github.com/astaxie/godoc) already). Go has a powerful tool to manage documentation natively. + +So how do we look up package information in documentation? For instance, if you want to get more details about the `builtin` package, use the `godoc builtin` command. Similarly, use the `godoc net/http` command to look up the `http` package documentation. If you want to see more details about specific functions, use the `godoc fmt Printf` and `godoc -src fmt Printf` commands to view the source code. + +Execute the `godoc -http=:8080` command, then open `127.0.0.1:8080` in your browser. You should see a localized golang.org. It can not only show the standard packages' information, but also packages in your `$GOPATH/pkg`. It's great for people who are suffering from the Great Firewall of China. + +## Other commands + +Go provides more commands than those we've just talked about. + + go fix // upgrade code from an old version before go1 to a new version after go1 + go version // get information about your version of Go + go env // view environment variables about Go + go list // list all installed packages + go run // compile temporary files and run the application + +There are also more details about the commands that I've talked about. You can use `go help ` to look them up. + +## Links + +- [Directory](preface.md) +- Previous section: [$GOPATH and workspace](01.2.md) +- Next section: [Go development tools](01.4.md) diff --git a/fa/working/01.4.md b/fa/working/01.4.md new file mode 100644 index 00000000..ff8175fd --- /dev/null +++ b/fa/working/01.4.md @@ -0,0 +1,483 @@ +# Go development tools + +In this section, I'm going to show you a few IDEs that can help you become a more efficient programmer, with capabilities such as intelligent code completion and auto-formatting. They are all cross-platform, so the steps I will be showing you should not be very different, even if you are not using the same operating system. + +## LiteIDE + +LiteIDE is an open source, lightweight IDE for developing Go projects only, developed by visualfc. + +![](images/1.4.liteide.png?raw=true) + +Figure 1.4 Main panel of LiteIDE + +LiteIDE features. + +- Cross-platform + - Windows + - Linux + - Mac OS +- Cross-compile + - Manage multiple compile environments + - Supports cross-compilation of Go +- Project management standard + - Documentation view based on $GOPATH + - Compilation system based on $GOPATH + - API documentation index based on $GOPATH +- Go source code editor + - Code outlining + - Full support of gocode + - Go documentation view and API index + - View code expression using `F1` + - Function declaration jump using `F2` + - Gdb support + - Auto-format with `gofmt` +- Others + - Multi-language + - Plugin system + - Text editor themes + - Syntax support based on Kate + - intelligent completion based on full-text + - Customized shortcuts + - Markdown support + - Real-time preview + - Customized CSS + - Export HTML and PDF + - Convert and merge to HTML and PDF + +### LiteIDE installation + +- Install LiteIDE + - [Download page](https://sourceforge.net/projects/liteide/files/) + - [Source code](https://github.com/visualfc/liteide) + + You need to install Go first, then download the version appropriate for your operating system. Decompress the package to directly use it. +- Install gocode + + You have to install gocode in order to use intelligent completion + + go get -u github.com/nsf/gocode + +- Compilation environment + + Switch configuration in LiteIDE to suit your operating system. + In Windows and using the 64-bit version of Go, you should choose win64 as the configuration environment in the tool bar. Then, choose `Options`, find `LiteEnv` in the left list and open file `win64.env` in the right list. + + GOROOT=c:\go + GOBIN= + GOARCH=amd64 + GOOS=windows + CGO_ENABLED=1 + + PATH=%GOBIN%;%GOROOT%\bin;%PATH% + 。。。 + + Replace `GOROOT=c:\go` to your Go installation path, save it. If you have MinGW64, add `c:\MinGW64\bin` to your path environment variable for `cgo` support. + + In Linux and using the 64-bit version of Go, you should choose linux64 as the configuration environment in the tool bar. Then, choose `Options`, find `LiteEnv` in the left list and open the `linux64.env` file in the right list. + + GOROOT=$HOME/go + GOBIN= + GOARCH=amd64 + GOOS=linux + CGO_ENABLED=1 + + PATH=$GOBIN:$GOROOT/bin:$PATH + 。。。 + + Replace `GOROOT=$HOME/go` to your Go installation path, save it. +- $GOPATH + $GOPATH is the path that contains a list of projects. Open the command tool (or press ``Ctrl+` ``in LiteIDE), then type `go help gopath` for more details. + It's very easy to view and change $GOPATH in LiteIDE. Follow `View - Setup GOPATH` to view and change these values. + +## Sublime Text + +Here I'm going to introduce you the Sublime Text 3 (Sublime for short) + GoSublime + gocode. Let me explain why. + +- Intelligent completion + + ![](images/1.4.sublime1.png?raw=true) + + Figure 1.5 Sublime intelligent completion +- Auto-format source files +- Project management + + ![](images/1.4.sublime2.png?raw=true) + + Figure 1.6 Sublime project management + +- Syntax highlight +- Free trial forever with no functional limitations. You may be prompted once in a while to remind you to purchase a license, but you can simply ignore it if you wish. Of course, if you do find that it enhances your productivity and you really enjoy using it, please purchase a copy of it and support its continued development! + +First, download the version of [Sublime](http://www.sublimetext.com/) suitable for your operating system. + +1. Press ``Ctrl+` ``, open the command tool and input the following commands. + + Applicable to Sublime Text 3: + +```Go +import urllib.request,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()) +``` + Applicable to Sublime Text 2: + +```Go +import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnotos.path.exists(ipp)elseNone;urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read());print('Please restart Sublime Text to finish installation') +``` + + Restart Sublime Text when the installation has finished. You should then find a `Package Control` option in the "Preferences" menu. + + ![](images/1.4.sublime3.png?raw=true) + + Figure 1.7 Sublime Package Control +2. To install GoSublime, SidebarEnhancements and Go Build, press `Ctrl+Shift+p` to open Package Control, then type `pcip` (short for "Package Control: Install Package"). + + ![](images/1.4.sublime4.png?raw=true) + + Figure 1.8 Sublime Install Packages + + Now type in "GoSublime", press OK to install the package, and repeat the same steps for installing SidebarEnhancements and Go Build. Once again, restart the editor when it completes the installation. +3. To verify that the installation is successful, open Sublime, then open the `main.go` file to see if it has the proper syntax highlighting. Type `import` to see if code completion prompts appear. After typing `import "fmt"`, type `fmt.` anywhere after the `import` declaration to see whether or not intelligent code completion for functions was successfully enabled. + + If everything is fine, you're all set. + + If not, check your $PATH again. Open a terminal, type `gocode`. If it does not run, your $PATH was not configured correctly. + +## Vim + +Vim is a popular text editor for programmers, which evolved from its slimmer predecessor, Vi. It has functions for intelligent completion, compilation and jumping to errors. + +vim-go is vim above an open-source go language using the most extensive development environment plug-ins + +The plugin address:[github.com/fatih/vim-go](https://github.com/fatih/vim-go) + +Vim plugin management are the mainstream [Pathogen](https://github.com/tpope/vim-pathogen) and [Vundle](https://github.com/VundleVim/Vundle.vim) +,But the aspects thereof are different. +Pathogen is to solve each plug-in after the installation of files scattered to multiple directories and poor management of the existence. Vundle is to solve the automatic search and download plug-ins exist. +These two plug-ins can be used simultaneously. + +1.Install Vundle + +```sh +mkdir ~/.vim/bundle +git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim +``` + +Edit .vimrc,Vundle the relevant configuration will be placed in the beginning([Refer to the Vundle documentation for details](https://github.com/VundleVim/Vundle.vim)) + +```sh +set nocompatible " be iMproved, required +filetype off " required + +" set the runtime path to include Vundle and initialize +set rtp+=~/.vim/bundle/Vundle.vim +call vundle#begin() + +" let Vundle manage Vundle, required +Plugin 'gmarik/Vundle.vim' + +" All of your Plugins must be added before the following line +call vundle#end() " required +filetype plugin indent on " required + +``` +2.Install Vim-go + +Edit ~/.vimrc,Add a line between vundle #begin and vundle #end: + +```sh + +Plugin 'fatih/vim-go' +``` + +Executed within Vim: PluginInstall + +3.Install YCM(Your Complete Me) to AutoComplete +Add a line to ~ / .vimrc: +```sh + +Plugin 'Valloric/YouCompleteMe' +``` +Executed within Vim: PluginInstall + + +![](images/1.4.vim.png?raw=true) + +Figure 1.8 Vim intelligent completion for Go + +1. Syntax highlighting for Go + + cp -r $GOROOT/misc/vim/* ~/.vim/ + +2. Enabling syntax highlighting + + filetype plugin indent on + syntax on + +3. Install [gocode](https://github.com/nsf/gocode/) + + go get -u github.com/nsf/gocode + + gocode will be installed in `$GOBIN` as default + +4. Configure [gocode](https://github.com/nsf/gocode/) + + ~ cd $GOPATH/src/github.com/nsf/gocode/vim + ~ ./update.sh + ~ gocode set propose-builtins true + propose-builtins true + ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" + lib-path "/home/border/gocode/pkg/linux_amd64" + ~ gocode set + propose-builtins true + lib-path "/home/border/gocode/pkg/linux_amd64" + + Explanation of gocode configuration: + + propose-builtins: specifies whether or not to open intelligent completion; false by default. + lib-path: gocode only searches for packages in `$GOPATH/pkg/$GOOS_$GOARCH` and `$GOROOT/pkg/$GOOS_$GOARCH`. This setting can be used to add additional paths. + +5. Congratulations! Try `:e main.go` to experience the world of Go! + +## Emacs + +Emacs is the so-called Weapon of God. She is not only an editor, but also a powerful IDE. + +![](images/1.4.emacs.png?raw=true) + +Figure 1.10 Emacs main panel of Go editor + +1. Syntax highlighting + + cp $GOROOT/misc/emacs/* ~/.emacs.d/ + +2. Install [gocode](https://github.com/nsf/gocode/) + + go get -u github.com/nsf/gocode + + gocode will be installed in `$GOBIN` as default +3. Configure [gocode](https://github.com/nsf/gocode/) + + ~ cd $GOPATH/src/github.com/nsf/gocode/vim + ~ ./update.bash + ~ gocode set propose-builtins true + propose-builtins true + ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" + lib-path "/home/border/gocode/pkg/linux_amd64" + ~ gocode set + propose-builtins true + lib-path "/home/border/gocode/pkg/linux_amd64" + +4. Install [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete) + Download and uncompress + + ~ make install DIR=$HOME/.emacs.d/auto-complete + + Configure ~/.emacs file + + ;;auto-complete + (require 'auto-complete-config) + (add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict") + (ac-config-default) + (local-set-key (kbd "M-/") 'semantic-complete-analyze-inline) + (local-set-key "." 'semantic-complete-self-insert) + (local-set-key ">" 'semantic-complete-self-insert) + + Follow this [link](http://www.emacswiki.org/emacs/AutoComplete) for more details. +5. Configure .emacs + + ;; golang mode + (require 'go-mode-load) + (require 'go-autocomplete) + ;; speedbar + ;; (speedbar 1) + (speedbar-add-supported-extension ".go") + (add-hook + 'go-mode-hook + '(lambda () + ;; gocode + (auto-complete-mode 1) + (setq ac-sources '(ac-source-go)) + ;; Imenu & Speedbar + (setq imenu-generic-expression + '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1) + ("func" "^func *\\(.*\\) {" 1))) + (imenu-add-to-menubar "Index") + ;; Outline mode + (make-local-variable 'outline-regexp) + (setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....") + (outline-minor-mode 1) + (local-set-key "\M-a" 'outline-previous-visible-heading) + (local-set-key "\M-e" 'outline-next-visible-heading) + ;; Menu bar + (require 'easymenu) + (defconst go-hooked-menu + '("Go tools" + ["Go run buffer" go t] + ["Go reformat buffer" go-fmt-buffer t] + ["Go check buffer" go-fix-buffer t])) + (easy-menu-define + go-added-menu + (current-local-map) + "Go tools" + go-hooked-menu) + + ;; Other + (setq show-trailing-whitespace t) + )) + ;; helper function + (defun go () + "run current buffer" + (interactive) + (compile (concat "go run " (buffer-file-name)))) + + ;; helper function + (defun go-fmt-buffer () + "run gofmt on current buffer" + (interactive) + (if buffer-read-only + (progn + (ding) + (message "Buffer is read only")) + (let ((p (line-number-at-pos)) + (filename (buffer-file-name)) + (old-max-mini-window-height max-mini-window-height)) + (show-all) + (if (get-buffer "*Go Reformat Errors*") + (progn + (delete-windows-on "*Go Reformat Errors*") + (kill-buffer "*Go Reformat Errors*"))) + (setq max-mini-window-height 1) + (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t)) + (progn + (erase-buffer) + (insert-buffer-substring "*Go Reformat Output*") + (goto-char (point-min)) + (forward-line (1- p))) + (with-current-buffer "*Go Reformat Errors*" + (progn + (goto-char (point-min)) + (while (re-search-forward "" nil t) + (replace-match filename)) + (goto-char (point-min)) + (compilation-mode)))) + (setq max-mini-window-height old-max-mini-window-height) + (delete-windows-on "*Go Reformat Output*") + (kill-buffer "*Go Reformat Output*")))) + ;; helper function + (defun go-fix-buffer () + "run gofix on current buffer" + (interactive) + (show-all) + (shell-command-on-region (point-min) (point-max) "go tool fix -diff")) +6. Congratulations, you're done! Speedbar is closed by default -remove the comment symbols in the line `;;(speedbar 1)` to enable this feature, or you can use it through `M-x speedbar`. + +## Eclipse + +Eclipse is also a great development tool. I'll show you how to use it to write Go programs. + +![](images/1.4.eclipse1.png?raw=true) + +Figure 1.1 Eclipse main panel for editing Go + +1. Download and install [Eclipse](http://www.eclipse.org/) +2. Download [goclipse](https://code.google.com/p/goclipse/) + [http://code.google.com/p/goclipse/wiki/InstallationInstructions](http://code.google.com/p/goclipse/wiki/InstallationInstructions) +3. Download gocode + + gocode in Github. + + https://github.com/nsf/gocode + + You need to install git in Windows, usually we use [msysgit](https://code.google.com/p/msysgit/) + + Install gocode in the command tool + + go get -u github.com/nsf/gocode + + You can install from source code if you like. +4. Download and install [MinGW](http://sourceforge.net/projects/mingw/files/MinGW/) +5. Configure plugins. + + Windows->Preferences->Go + + (1).Configure Go compiler + + ![](images/1.4.eclipse2.png?raw=true) + + Figure 1.12 Go Setting in Eclipse + + (2).Configure gocode(optional), set gocode path to where the gocode.exe is. + + ![](images/1.4.eclipse3.png?raw=true) + + Figure 1.13 gocode Setting + + (3).Configure gdb(optional), set gdb path to where the gdb.exe is. + + ![](images/1.4.eclipse4.png?raw=true) + + Figure 1.14 gdb Setting +6. Check the installation + + Create a new Go project and hello.go file as following. + + ![](images/1.4.eclipse5.png?raw=true) + + Figure 1.15 Create a new project and file + + Test installation as follows.(you need to type command in console in Eclipse) + + ![](images/1.4.eclipse6.png?raw=true) + + Figure 1.16 Test Go program in Eclipse + +## IntelliJ IDEA + +People who have worked with Java should be familiar with this IDE. It supports Go syntax highlighting and intelligent code completion, implemented by a plugin. + +1. Download IDEA, there is no difference between the Ultimate and Community editions + + ![](images/1.4.idea1.png?raw=true) + +2. Install the Go plugin. Choose `File - Setting - Plugins`, then click `Browser repo`. + + ![](images/1.4.idea3.png?raw=true) + +3. Search `golang`, double click `download and install` and wait for the download to complete. + + ![](images/1.4.idea4.png?raw=true) + + Click `Apply`, then restart. +4. Now you can create a Go project. + + ![](images/1.4.idea5.png?raw=true) + + Input the position of your Go sdk in the next step -basically it's your $GOROOT. + +( ***See a [blog post](http://wuwen.org/tips-about-using-intellij-idea-and-go/) for setup and use IntelliJ IDEA with Go step by step *** ) + + +## Visual Studio VSCode + +This is an awesome text editor released as open source cross platform my Microsoft which takes the development experience to a whole new level, https://code.visualstudio.com/. It has everything a modern text editor is expected to have and despite being based on the same backend that atom.io is based, it is very fast. + +It works with Windows, Mac, Linux. It has go package built, it provides code linting. + +## Atom + +Atom is an awesome text editor released as open source cross platform, built on Electron , and based on everything we love about our favorite editors. We designed it to be deeply customizable, but still approachable using the default configuration. + +Download: https://atom.io/ + +## Gogland + +Gogland is the codename for a new commercial IDE by JetBrains aimed at providing an ergonomic environment for Go development. + +The official version is not yet released。 + +Download:https://www.jetbrains.com/go/ + +## Links + +- [Directory](preface.md) +- Previous section: [Go commands](01.3.md) +- Next section: [Summary](01.5.md) diff --git a/fa/working/01.5.md b/fa/working/01.5.md new file mode 100644 index 00000000..8bb67ba1 --- /dev/null +++ b/fa/working/01.5.md @@ -0,0 +1,9 @@ +# 1.5 Summary + +In this chapter, we talked about how to install Go using three different methods including from source code, the standard package and via third-party tools. Then we showed you how to configure the Go development environment, mainly covering how to setup your `$GOPATH`. After that, we introduced some steps for compiling and deploying Go programs. We then covered Go commands, including the compile, install, format and test commands. Finally, there are many powerful tools to develop Go programs such as LiteIDE, Sublime Text, VSCode, Atom, Goglang, Vim, Emacs, Eclipse, IntelliJ IDEA, etc. You can choose any one you like exploring the world of Go. + +## Links + +- [Directory](preface.md) +- Previous section: [Go development tools](01.4.md) +- Next chapter: [Go basic knowledge](02.0.md)