задний план
Я разработчик Java, и я сделал много программного обеспечения с открытым исходным кодом.Часто существует небольшой спрос на предоставление справочных программ командной строки под терминалом.Как правило, у каждого есть несколько способов удовлетворить этот спрос.
- Напишите пакет или оболочку (дважды для Windows и Linux)
- Используйте для решения языки программирования (golang, python — хороший кроссплатформенный выбор)
Программисты ленивы, поэтому я не хочу писать это дважды ~ Я давно писал подобные программы на Python, но упакованные результаты относительно велики.С другой стороны, язык Go становится все более и более популярным, который также является моим любимым языком программирования и поддерживает кроссплатформенность, так что выбирайте его.
В этой небольшой статье я научу вас написать небольшую программу, которая может проверять местную погоду.Это относительно просто.Вы можете сделать свой любимый небольшой инструмент, изучив эту статью.
Полный код можно найти в моемGithubПроверять.
Установка среды
Мы должны подготовить среду языка Go, прежде чем начать, если вы уже установили, этот шаг может быть квалифицированным. ты сможешьздесьЗагрузите последнюю версию языковой версии Go, если ваша сетевая среда вынуждена выглядеть следующим образом.
ты сможешьГолангКитайЗагрузите пакет последней версии. Есть несколько способов установки языковой среды Go, мы выбираем самый простой способ:Стандартная установка пакета.
Скачать для Mac.pkg
Файл пакета в конце, скачать под Windows.msi
В конце файла можно сдуру установить после скачивания.
Будьте осторожны, чтобы не выбрать неправильную архитектуру операционной системы.Установка исходного кода Linux здесь не рассматривается.
Настроить переменные среды
Узнайте много языков программирования, необходимые вам необходимо настроить переменные среды, установить программное обеспечение, они также на самом деле имеют часть программы молча помогите нам сделать эту вещь перед нами, установите язык Go, здесь мы понимаем под Перейти к настройке языковой среды и как настроить.
- GOROOT: путь установки Go
- GOPATH: Сообщите команде Go и другим связанным инструментам, где найти пакеты Go, установленные в вашей системе.
Затем давайте создадим рабочий каталог для хранения пакета исходного кода, написанного нами~
Под Windows предполагается, чтоD:/go
этот каталог,Linux/MacOSXСледующее предположение~/workspace/golang
этот каталог. я в настоящее времяMacOSXsystem, установите переменную среды в соответствии с этим.
- добавить переменную окружения
export GOROOT=/usr/local/go
- добавить переменную окружения
export GOPATH=/Users/biezhi/workspace/golang
- Изменить системные переменные среды
export PATH=$PATH:$GOPATH/bin
пройти тест
# biezhi in ~
» go version
go version go1.8.3 darwin/amd64
Готово, следующий контент требует от вас основ языка программирования, иначе вы его не съедите.
Некоторые различия с язвом Java
Здесь мы говорим о нескольких различиях, и мы не можем покрыть их всеми для удовлетворения потребностей этой статьи.
объявить переменные, константы
Ява
private String name = "biezhi";
public static final String VERSION = "0.2.1";
Голанг
name := "biezhi"
const version = "0.2.1"
Гномье масло, очень просто~
классы и объекты
Ява
public class Config {
private String key;
private String value;
// getter and setter
}
// 使用
Config config = new Config();
config.setKey("name");
config.setValue("biezhi");
Голанг
type Config struct {
key string
value string
}
// 使用
conf := Config{key: "name", value: "biezhi"}
Короткое масло, и тм лаконично. . .
В golang нет ключевого слова class, но type вводится, и в golang больше внимания уделяется типу.
возвращаемое значение функции
Ява
public String getFileName(){
return "不可描述.jpg";
}
Здесь, если вам нужно вернуть несколько значений, вам нужно заменить его классом или типом карты.
Голанг
func getFileNmae() (string, error) {
return "可以描述.jpg", nil
}
Язык Go естественным образом поддерживает несколько возвратных значений (ведь восходящие звезды, социальное общество)
Операция закрытия потока в Java обычно пишет такой код
try {
in.balabala~
} catch(Exception e) {
// 处理异常
} finally {
in.close();
}
В Go нет finally, попробуйте отложить
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
dst, err := os.Create(dstName)
if err != nil {
return
}
written, err = io.Copy(dst, src)
dst.Close()
src.Close()
return
}
CopyFile
Метод просто реализует функцию копирования содержимого файла и копирует содержимое исходного файла в целевой файл. На первый взгляд проблем нет, но ресурсы в Голанге тоже нужно освобождать.os.Create
При вызове метода произошла ошибка, следующий операторreturn
, в результате чего два открытых файла не могут быть освобождены. В настоящее время,defer
Вот где это пригодится.
ФронтBB
Настолько, что мы просто имели в виду, как выглядит код Go. Мы начали следить за официальной темой, если вы видите часть основы для фонда до сих пор не понимаю, книги, материалы (не могу найти личное письмо).
Реализация нативного письма
Я не буду учить вас пользоваться той или иной библиотекой сразу, это очень безответственно, вы должны знать, как это делают люди в эпоху без библиотек, когда есть более удобные инструменты, чтобы облегчить меня, в этом процессе вы можете поймете, как использовать API, с которыми вы раньше не сталкивались, и вы сможете гибко использовать их в программировании в долгосрочной перспективе.
Вот несколько основных пакетов для понимания:
-
fmt
: Пакет форматирования, который реализует форматированный ввод-вывод, аналогичный printf и scanf языка C. -
encoding/json
: собственный пакет синтаксического анализа JSON. -
net/http
: отправить http-запрос -
flag
: Предоставляет ряд функциональных интерфейсов для разбора параметров командной строки. -
io/ioutil
: обработка ввода-вывода
После того, как у нас есть эти пакеты, мы пишемHello World
О чудо, мой проект называетсяweather-cli
пройти черезflag.XxxVar()
Метод привязывает флаг к переменной, которая возвращает тип значения, например
package main
import (
"fmt"
"flag"
"os"
)
func main() {
var city string
flag.StringVar(&city, "c", "上海", "城市中文名")
flag.Parse()
fmt.Println("城市是:", city)
}
Попробуйте
# biezhi in ~/workspace/golang/src/github.com/biezhi/weather-cli
» go build && ./weather-cli
城市是: 上海
» go build && ./weather-cli -c 北京
城市是: 北京
Аргумент анализа относительно прост, в этой демонстрации мы добавляем два параметра, первый - это город, второй - отобразить день, конкретный код следующим образом:
func main() {
var city string
var day string
flag.StringVar(&city, "c", "上海", "城市中文名")
flag.StringVar(&day, "d", "今天", "可选: 今天, 昨天, 预测")
flag.Parse()
}
На данный момент параметры, вводимые терминалом, могут быть получены, затем пришло время найти интерфейс для вызова API погоды, я нашелэтоБесплатный интерфейс API для вызова. Нам нужно написать метод для HTTP-запросов.
func Request(url string) (string, error) {
response, err := http.Get(url)
if err != nil {
return "", err
}
defer response.Body.Close()
body, _ := ioutil.ReadAll(response.Body)
return string(body), nil
}
Конечно, это удобнее, чем Java.Эта функция очень проста.Введите URL-адрес и верните тело ответа в виде строки. Мы можем передать входной город, по умолчанию上海
.
var city string
var day string
flag.StringVar(&city, "c", "上海", "城市中文名")
flag.StringVar(&day, "d", "今天", "可选: 今天, 昨天, 预测")
flag.Parse()
var body, err = Request(apiUrl + city)
if err != nil {
fmt.Printf("err was %v", err)
return
}
Затем нам нужно определить некоторые类型
Для хранения JSON в языке Java используется Class. Как этот тип структуры определяется по возвращаемому результату API, я пишу их отдельноtypes.go
в файле.
// 响应
type Response struct {
Status int `json:"status"`
CityName string `json:"city"`
Data Data `json:"data"`
Date string `json:"date"`
Message string `json:"message"`
Count int `json:"count"`
}
// 响应数据
type Data struct {
ShiDu string `json:"shidu"`
Quality string `json:"quality"`
Ganmao string `json:"ganmao"`
Yesterday Day `json:"yesterday"`
Forecast []Day `json:"forecast"`
}
// 某一天的数据
type Day struct {
Date string `json:"date"`
Sunrise string `json:"sunrise"`
High string `json:"high"`
Low string `json:"low"`
Sunset string `json:"sunset"`
Aqi float32 `json:"aqi"`
Fx string `json:"fx"`
Fl string `json:"fl"`
Type string `json:"type"`
Notice string `json:"notice"`
}
После определения типа JSON, полученный из HTTP-запроса, может быть преобразован в определенный тип.
var r Response
err = json.Unmarshal([]byte(body), &r)
if err != nil {
fmt.Printf("\nError message: %v", err)
}
if r.Status != 200 {
fmt.Printf("获取天气API出现错误, %s", r.Message)
return
}
Здесь используется парсинг JSON, который поставляется с Go (эй, у меня нет большой Java...), и, наконец, мы выводим полученные данные, и все в порядке.
func Print(day string, r Response) {
fmt.Println("城市:", r.CityName)
if day == "今天" {
fmt.Println("湿度:", r.Data.ShiDu)
fmt.Println("空气质量:", r.Data.Quality)
fmt.Println("温馨提示:", r.Data.Ganmao)
} else if day == "昨天" {
fmt.Println("日期:", r.Data.Yesterday.Date)
fmt.Println("温度:", r.Data.Yesterday.Low, r.Data.Yesterday.High)
fmt.Println("风量:", r.Data.Yesterday.Fx, r.Data.Yesterday.Fl)
fmt.Println("天气:", r.Data.Yesterday.Type)
fmt.Println("温馨提示:", r.Data.Yesterday.Notice)
} else if day == "预测" {
fmt.Println("====================================")
for _, item := range r.Data.Forecast {
fmt.Println("日期:", item.Date)
fmt.Println("温度:", item.Low, item.High)
fmt.Println("风量:", item.Fx, item.Fl)
fmt.Println("天气:", item.Type)
fmt.Println("温馨提示:", item.Notice)
fmt.Println("====================================")
}
} else {
fmt.Println("大熊你是想刁难我胖虎 ?_?")
}
}
На данный момент гаджет готов к работе, давайте попробуем
# biezhi in ~/workspace/golang/src/github.com/biezhi/weather-cli
» go build && ./weather-cli
城市: 上海
湿度: 72%
空气质量: 良
温馨提示: 极少数敏感人群应减少户外活动
» ./weather-cli -c 北京
城市: 北京
湿度: 78%
空气质量: 轻度污染
温馨提示: 儿童、老年人及心脏、呼吸系统疾病患者人群应减少长时间或高强度户外锻炼
Реализовано с помощью сторонней библиотеки
Здесь мы используем популярную в отрасли библиотекуcli,这个家伙怎么使用呢? Создаватьcli_main.go
документ
package main
import (
"fmt"
"os"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Name = "greet"
app.Usage = "fight the loneliness!"
app.Action = func(c *cli.Context) error {
fmt.Println("Hello friend!")
return nil
}
app.Run(os.Args)
}
Это пример с официального сайта, запустите его и попробуйте
» go build cli_main.go && ./cli_main
Hello friend!
Чтобы реализовать нашу небольшую программу выше, нам нужно использоватьflag
Эта функция, код, реализованный библиотекой, выглядит следующим образом
func main() {
app := cli.NewApp()
app.Name = "weather-cli"
app.Usage = "天气预报小程序"
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "city, c",
Value: "上海",
Usage: "城市中文名",
},
cli.StringFlag{
Name: "day, d",
Value: "今天",
Usage: "可选: 今天, 昨天, 预测",
},
}
app.Action = func(c *cli.Context) error {
city := c.String("city")
day := c.String("day")
var body, err = Request(apiUrl + city)
if err != nil {
fmt.Printf("err was %v", err)
return nil
}
var r Response
err = json.Unmarshal([]byte(body), &r)
if err != nil {
fmt.Printf("\nError message: %v", err)
return nil
}
if r.Status != 200 {
fmt.Printf("获取天气API出现错误, %s", r.Message)
return nil
}
Print(day, r)
return nil
}
app.Run(os.Args)
}
Я дал весь код напрямую, просто40
Многострочное завершено ~ запустить его
» go build -o weather-cli utils.go types.go cli_main.go && ./weather-cli
城市: 上海
湿度: 72%
空气质量: 良
温馨提示: 极少数敏感人群应减少户外活动
» go build -o weather-cli utils.go types.go cli_main.go && ./weather-cli --city 北京
城市: 北京
湿度: 78%
空气质量: 轻度污染
温馨提示: 儿童、老年人及心脏、呼吸系统疾病患者人群应减少长时间或高强度户外锻炼
Ниже мы узнаем, как упаковать этот апплет в двоичное использование под каждой платформой, и как сжать двоичный пакет сделать его меньше!
Упаковать и сжать
Упакованы в виде программ для отдельных операционных систем
линукс 64 бит
GOOS=linux GOARCH=amd64 go build ...
Windows 64 бит
GOOS=windows GOARCH=amd64 go build ...
MacOSX
GOOS=darwin GOARCH=amd64 go build ...
Если вы попытаетесь упаковать, результирующий двоичный размер будет примерно7.2M
Этот объем немного великоват, мы можем использовать некоторые приемы, чтобы уменьшить его.
Сначала добавьте параметр компиляции -ldflags
go build -ldflags '-w -s' -o weather-cli utils.go types.go cli_main.go
После выполнения обнаруживается, что программа имеет только5.4M
Он стал меньше, но все равно для нас великоват.Я буду писать десятки строк кода и не обязательно генерировать такой большой размер.Давайте воспользуемся другим артефактом.upx, если он у вас не установлен, вы можете скачать и установить его на официальном сайте.
go build -ldflags '-w -s' -o weather-cli utils.go types.go cli_main.go && upx ./weather-cli
приди и посмотри
» ll -la
drwxr-xr-x 12 biezhi staff 384 Nov 1 18:44 .git
-rw-r--r-- 1 biezhi staff 1.1K Sep 3 20:59 LICENSE
-rw-r--r-- 1 biezhi staff 710 Nov 1 18:32 README.md
-rwxr-xr-x 1 biezhi staff 5.4M Nov 1 18:41 cli_main
-rw-r--r-- 1 biezhi staff 905 Nov 1 18:18 cli_main.go
-rw-r--r-- 1 biezhi staff 609 Nov 1 18:19 main.go
-rw-r--r-- 1 biezhi staff 808 Nov 1 16:56 types.go
-rw-r--r-- 1 biezhi staff 1.4K Nov 1 18:19 utils.go
-rwxr-xr-x 1 biezhi staff 2.0M Nov 1 18:44 weather-cli
Только2.0M
Вот и все, все водители с удовольствием учатся~ Если вы хотите увидеть больше интересных моментов разработки, вы можете следить за моей колонкой."Ван Цзюэ технологии темной комнате".Или напишите мне.