Прогулка пятая. Китайский квартал

СеGOдня будем делать первую полезную программу. Собственно, ваших знаний достаточно, чтобы использовать go. Но еще недостаточно чтобы использовать его качественно. Простые проекты — это то, что нам надо.

http — на просторах web

Go вообще отличается разнообразием стандартных модулей (пакетов). Недавно, вот, появился модуль для работы с http запросами/ответами. А с его помощью можно сделать… Ой, аж глаза разбегаются.

Ну вот мне, например, нужен был консольный простой переводчик. Google Translate имеет удобный ajax API. Его и будем использовать. Кто знаком немного с HTTP протоколом, тот помнит, что запросы бывают GET и POST, и с их помощью можно передавать аргументы серверу. GET-запрос имел вид URL: «http://server/path/script?arg1=&arg2=y&arg3=z».

Если почитать про Google APIs, то узнаем, что запросы на гугл переводчик выглядят как:

http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=<ваше слово>&langpair=<откуда>|<куда>

Запрос можно послать с помощью функции http.Get(). Ответ придет в виде структуры типа Response. Тело ответа находится в поле Body. Его можно считать с помощью модуля io/ioutils, а потом преобразовать в строку с помощью функции string(). Готово. Осталось только эту строку распарсить как нам нужно.

flag — опции командной строки

Для этого есть модуль flag. Вначале модуль должен распарсить опции с помощью функции flag.Parse(). Потом их можно различным образом считать. В простейшем случае — в цикле. flag.NArg() возвращает количество аргументов командной строки, а flag.Arg(i) возвращает i-й аргумент.

Зная про http и про flag и еще несколько модулей, пишем нашу программу.

package main

import (
	"io/ioutil"
	"flag"
	"fmt"
	"http"
	"strings"
	"os"
)

/* 
 * Send GET request to Google Translate API and get the response
 */
func translate(fromLang, toLang, word string) (res string, ok bool) {
	r,_,_ := http.Get("http://ajax.googleapis.com/ajax/services/language/translate?"+
										"v=1.0&q=" + http.URLEscape(word) + "&langpair=" + fromLang + "|" + toLang)
	b,err := ioutil.ReadAll(r.Body)
	r.Body.Close()

	if err == nil {
		res = string(b)
	}
	return
}

func main() {
	/* Parse command line options */
	flag.Parse()
	if flag.NArg() != 3 {
		fmt.Printf("Usage: gotr <from> <to> <word>\n")
		os.Exit(0)
	}

	langFrom := flag.Arg(0)
	langTo   := flag.Arg(1)
	word     := flag.Arg(2)

	/* Get the response from google server */
	s,_ := translate(langFrom, langTo, word)

	/* Parse the response and get the translation */
	tokens := strings.Split(s, "\"", -1)
	for i:=0; i<cap(tokens); i++ {
		if tokens[i] == "translatedText" {
			fmt.Printf("%s -> %s\n", word, tokens[i+2])
			break
		}
	}
}

Я назвал проект trago («translate»+»google», а по-испански — выпивка). Собираем, запускаем:

./trago es ru trago
trago -> пить

Готово. Пишите побольше полезноGo!


Домашнее задание

Попробуйте попользовать чьё-то API, если хотите поработать с http (гисметео, твиттер, википедия).

Реклама

2 comments on “Прогулка пятая. Китайский квартал

  1. dr.Who:

    Пардон, а что значит r,_,_ := … ? Что означают прочерки в этой конструкции?

    • В Go функции могут возвращать несколько значений. Например, http.Get() возвращал объект-запрос (r), ошибку и еще что-то. Последние два возвращаемых значения нас не интересуют. Поэтому мы заменяем их на подчеркивания. Это штука (подчеркивание) называется «black indentifier».

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s