Страница 1 из 4
golang
Добавлено: Ср, 26 апреля 2017, 10:36:05
dyvniy
Кому и зачем нужен го? Вэбу (
https://habrahabr.ru/post/274099/50 оттенков ошибок)
https://habrahabr.ru/company/mailru/blog/314804/https://github.com/golang/go/wiki/GoForCPPProgrammersНаследование
https://toster.ru/q/286213Код: Выделить всё
package main
import "fmt"
type AnimalIntf interface {
Walk() AnimalIntf
Say() AnimalIntf
}
type Animal struct {
animal AnimalIntf
Name string
}
type Rabbit struct {
Animal
}
// Animal
func NewAnimal(name string) *Animal {
animal := new(Animal)
animal.animal = animal
animal.Name = name
return animal
}
//Метод Walk у каждого свой
func (this *Animal) Walk() AnimalIntf {
fmt.Println("I walk", this.Name)
return this.animal
}
//Метод Say общий
func (this *Animal) Say() AnimalIntf {
fmt.Println("Im Animal and my Name is", this.Name)
return this.animal
}
// Rabbit
func NewRabbit(name string) *Rabbit {
rabbit := new(Rabbit)
rabbit.animal = rabbit
rabbit.Name = name
return rabbit
}
//Метод Walk изменяется для Rabbit и работает корректно
func (this *Rabbit) Walk() AnimalIntf {
this.Animal.Walk()
fmt.Println("...and Jump")
return this.animal
}
func main() {
animal := NewAnimal("Зверь")
animal.Walk().Say().Walk()
fmt.Println("\n---------------------\n")
rabbit := NewRabbit("Кроль")
rabbit.Walk().Say().Walk()
}
Коллегам оно не нравится
текущий рабочий сервер для Goland:
http://idea.ibdyr.com
Добавлено: Ср, 26 апреля 2017, 16:45:12
dyvniy
Джетбрэйновская IDE сыровата
Из консоли нормлаьно билдится и работает.
По крайней мере консольные приложения.
Напоминает делфи отсутствием зависимостей, только гуя нет.
Добавлено: Чт, 27 апреля 2017, 11:49:17
dyvniy
Добавлено: Чт, 31 августа 2017, 12:12:51
dyvniy
https://gobyexample.com/command-line-argumentsКод: Выделить всё
// [_Command-line arguments_](http://en.wikipedia.org/wiki/Command-line_interface#Arguments)
// are a common way to parameterize execution of programs.
// For example, `go run hello.go` uses `run` and
// `hello.go` arguments to the `go` program.
package main
import "os"
import "fmt"
func main() {
// `os.Args` provides access to raw command-line
// arguments. Note that the first value in this slice
// is the path to the program, and `os.Args[1:]`
// holds the arguments to the program.
argsWithProg := os.Args
argsWithoutProg := os.Args[1:]
// You can get individual args with normal indexing.
arg := os.Args[3]
fmt.Println(argsWithProg)
fmt.Println(argsWithoutProg)
fmt.Println(arg)
}
$ go build command-line-arguments.go
$ ./command-line-arguments a b c d
[./command-line-arguments a b c d]
[a b c d]
c
Добавлено: Чт, 31 августа 2017, 12:29:45
dyvniy
https://stackoverflow.com/questions/35528180/how- ... ternal-python-script-in-golangКод: Выделить всё
package main
import (
"log"
"os"
"os/exec"
)
func main() {
log.Println(os.Args)
if len(os.Args) == 1 {
return
}
cmd := exec.Command(os.Args[1], os.Args[2:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
log.Println(cmd.Run())
}
Код: Выделить всё
test.py:
import sys
print sys.argv
usage:
$ go run test.go python test.py 1 two 3 four
2016/02/20 21:45:42 [/tmp/go-build772613382/command-line-arguments/_obj/exe/test python test.py 1 two 3 four]
['test.py', '1', 'two', '3', 'four']
2016/02/20 21:45:42 <nil>
Добавлено: Пн, 4 сентября 2017, 17:43:27
dyvniy
+ QML
https://4gophers.ru/articles/redaktor-na-go-i-qml/#.Wa1mA8gjFHY- Спойлер
- Редактор на Go и QML
Вольный пересказ документации к QML, адаптированный для языка программирования golang.
Все манипуляции производились на убунте. Не обещаю, что это взлетит на других дистрах. И вообще не факт, что будет работать на винде. Но, чем черт не шутит?
QML - хорошая вещь для написания десктопных интерфейсов. Сейчас активно пилится пакет go-qml. Пока что, этот пакет еще не достаточно стабилен, но уже многое умеет.
Надо заметить, что в этом примере не будет использоваться мощный инструмент RegisterType, который позволяет использовать свои типы в QML
Презентация возможностей пакета в коротком видео.
Установка Qt
Для моей убунты 12.04 сперва нужно установить зависимости.
$ sudo add-apt-repository ppa:ubuntu-sdk-team/ppa
$ sudo apt-get update
$ sudo apt-get install ubuntu-sdk qtbase5-private-dev qtdeclarative5-private-dev libqt5opengl5-dev
Правда, есть одно но. Стандартная установка затащит Qt версии 5.0.1, а в ней нет, например, QtQuick.Controls. Поэтому немного поизвращаемся с установкой свежей версии.
Самый удобный вариант установить последнюю версию Qt - это воспользоваться .run файлом с оф. сайта. Место для установки можно выбрать любое. После установки, чтобы приложение с go-qml могли нормально собираться, нужно указать где находятся исходники нашей версии библиотеки:
$ export LD_LIBRARY_PATH=/home/artem/Qt5.2.1/5.2.1/gcc/lib:$LD_LIBRARY_PATH
Теперь устанавливаем сам пакет go-qml:
$ go get gopkg.in/qml.v0
Простая программа
Для проверки правильности установки и работоспособности пакета напишем минимальную программу, которая почти ничего не делает.
package main
import (
"fmt"
"gopkg.in/qml.v0"
"os"
)
func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
func run() error {
qml.Init(nil)
engine := qml.NewEngine()
component, err := engine.LoadFile("Example.qml")
if err != nil {
return err
}
win := component.CreateWindow(nil)
win.Show()
win.Wait()
return nil
}
Любая Go программа, работающая с QML, должна выполнять несколько шагов:
Инициализировать пакет qml (qml.Init(nil))
Создать движок для загрузки и выполнения QML контента (engine := qml.NewEngine())
Сделать значения и типы из Go доступными для QML (Context.SetVar и RegisterType)
Загружать QML контент (component, err := engine.LoadFile("Main.qml"))
Создавать новое окно с контентом (win := component.CreateWindow(nil))
Показывать созданное окно и ждать его закрытия (win.Show(), win.Wait())
И очень простой QML код из файла Example.qml, который создает регион с текстом:
import QtQuick 2.0
Rectangle {
width: 360
height: 360
color: "grey"
Text {
id: windowText
anchors.centerIn: parent
text: "Hello QML in Go!"
}
}
В результате должно полуится серенькое окно с текстом:
img
Кнопки для редактора
Теперь можем приступать к созданию нашего редактора. Начнем с кнопочек открытия и сохранения файла. Как всегда, есть два способа. В первом случае, мы сделаем отдельный файл с названием Botton.qml и содержанием:
import QtQuick 2.0
Rectangle {
id: button
radius: 6
border.width: 3
border.color: "#ffffff"
width: 150; height: 75
property string label: ""
color: "#eeeeee"
signal buttonClick()
onButtonClick: {
}
Text{
id: buttonLabel
anchors.centerIn: parent
text: label
}
MouseArea {
id: buttonMouseArea
anchors.fill: parent
onClicked: buttonClick()
}
}
Это будет новый тип в QML который мы можем использовать в нашем главном файле. Не нужно писать ни каких импортов, так как Button.qml находится в той же папке, что и Example.qml
import QtQuick 2.0
Rectangle{
width: 360
height: 360
color: "grey"
Button{
id: loadButton
label: "Load"
onButtonClick: {
console.log("Hello!")
}
}
}
Вполне работоспособный пример, который выглядит примерно вот так: img
При клике на кнопку, в консоли будет писаться "Hello worl!".
Готовые компоненты
Такой подход дает полный контроль над внешним видом и поведением компонента, но требует больших временных затрат. Поэтому будем обходить гору и воспользуемся компонентом ToolButton из QtQuick.Controls:
import QtQuick 2.0
import QtQuick.Controls 1.0
Rectangle {
width: 360
height: 360
color: "grey"
ToolButton {
id: loadButton
x: 8
y: 8
text: "Load"
clicked: {
console.log("Load")
}
}
ToolButton {
id: saveButton
x: 70
y: 8
text: {
console.log("Save")
}
}
}
Теперь у нас есть две кнопочки:
img
Добавим немного жизни и радости к этому скучному дизайну. Создадим отдельный тип кнопок основанный на ToolButton и добавим к нему стилей QtQuick.Controls.Styles
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.1
ToolButton {
style: ButtonStyle {
background: Rectangle {
implicitWidth: 100
implicitHeight: 25
border.width: control.activeFocus ? 2 : 1
border.color: "#888"
radius: 4
gradient: Gradient {
GradientStop { position: 0 ; color: control.pressed ? "#ccc" : "#eee" }
GradientStop { position: 1 ; color: control.pressed ? "#aaa" : "#ccc" }
}
}
}
}
Используем этот тип в основном файле. А за одно, добавим многострочное текстовое поле для редактирования:
import QtQuick 2.0
import QtQuick.Controls 1.0
Rectangle {
width: 360
height: 360
color: "grey"
TextArea {
id: textArea
x: 8
y: 74
width: 344
height: 278
}
ExampleButton {
id: loadButton
x: 8
y: 8
text: "Load"
onClicked: {
console.log("Load")
}
}
ExampleButton {
id: saveButton
x: 140
y: 8
text: "Save"
onClicked: {
console.log("Save")
}
}
}
В итоге, получается готовый интерфейс нашего маленького приложения.
img
Реализуем логику
Добавляем файловый диалог и загрузку файлов для редактирования. Для этого используем компоненты из QtQuick.Dialogs
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Dialogs 1.0
Rectangle {
ExampleButton {
id: loadButton
//...
onClicked: {
console.log("Load")
fileDialogLoad.open()
}
}
//...
FileDialog {
id: fileDialogLoad
folder: "."
title: "Choose a file to open"
selectMultiple: false
onAccepted: {
console.log("Accepted: " + fileDialogLoad.fileUrl)
}
}
}
onAccepted - сработает тогда, когда в диалоговом окне будет выбран нужный файл.
Следующий шаг - самое интересное. Научимся передавать значения из QML в Go и наоборот. Для этого сделаем отдельный тип Editor:
type Editor struct {
Text string
}
func (e *Editor) SelectFile(fileUrl string) {
fmt.Println("Selected file: ", fileUrl)
e.Text = fileUrl
qml.Changed(e, &e.Text) // нужно, чтобы qml узнал о обновлении переменной
}
Как видно, метод SelectFile получает строку и записывает ее в параметр Text. Нужно привыкнуть пользоваться конструкцией qml.Changed(e, &e.Text) - именно этот вызов говорит нашему приложению что нужно обновить параметры в qml.
Пока не совсем понятно, зачем все это. Нужно передать этот тип в QML. Для этого есть методы SetVar, SetVars.
func run() error {
//...
context := engine.Context()
context.SetVar("editor", &Editor{})
//...
}
Так, все немного проясняется. Теперь нужно как-то захендлить Go переменную в qml коде. И тут нет ничего сложного:
TextArea {
//...
text: editor.text
}
ExampleButton {
id: saveButton
//...
onClicked: {
console.log("Save")
editor.saveFile(textArea.text)
}
}
FileDialog {
//...
onAccepted: {
console.log("Accepted: " + fileDialogLoad.fileUrl)
editor.selectFile(fileDialogLoad.fileUrl)
}
}
Ага, теперь все понятно. editor.text - это обращение к параметру Editor.Text, a editor.selectFile(fileDialogLoad.fileUrl) - это вызов метода Editor.SelectFile(fileUrl string)
Последний штрих - это, собственно, работа с файлами. Загрузка контента и сохранение изменений:
type Editor struct {
Text string
FileUrl string
}
func (e *Editor) SelectFile(fileUrl string) {
fmt.Println("Selected file: ", fileUrl)
e.FileUrl = strings.Replace(fileUrl, "file:/", "", 1)
dat, err := ioutil.ReadFile(e.FileUrl)
if err != nil {
log.Println(err)
}
e.Text = string(dat)
}
func (e *Editor) SaveFile(text string) {
dat := []byte(text)
err := ioutil.WriteFile(e.FileUrl, dat, 0644)
if err != nil {
log.Println(err)
}
}
Вот и все. Наш маленький редактор, написанный с использованием Go и QML готов. Теперь можно браться за написание своей вижуал студии. Все исходники можно стянуть с гитхаба.