Рубрики
Без рубрики

Переход от Python в Голанан и почему программисты Python должны рассмотреть это.

Вступление с тех пор, как я начал программировать языки высокого уровня, как Python, Ruby и Lua, … Теги с Go, Python.

вступление

С тех пор как я начал программировать языки высокого уровня, например, Python, Ruby и Lua, всегда были моими языками выбора для моих личных проектов. Я также устанавливался очень незначительным количеством C и C ++, большинство из которых были из-за моей небольшой коллекции Arduino досок. Если вы когда-либо использовали Python, Ruby, либо Lua, вы, вероятно, слышали, что они называются интерпретирован Языки. Это означает, что когда вы их устанавливаете, вам никогда не нужно запускать какой-либо компилятор. В Windows все, что вам нужно сделать, чтобы запустить их, это либо дважды щелкнуть или запустить python myscript.py В каталоге скрипта и он работает. Go это скомпилирован Язык, что означает, что он должен быть скомпилирован в машинный код до того, как он может быть запущен. Это имеет преимущество в том, чтобы быть Многое быстрее, чем интерпретированный язык. Известно, что большинство компиляционных языков, особенно таких как C и Java, имеет несколько крутой кривой обучения для начинающих. Иди особенный в этом отношении, поскольку он пытается преодолеть разрыв между двумя типами языков, скомпилированным как C, но с более удобным маршрутом для кодирования, например, Python. Этот пост на самом деле не является учебником, но в основном руководство для таких людей, как я, которые используются для интерпретации и динамически напечатанных языков, таких как Python, в переходе на статически набранный и скомпилированный язык, такой как Голанг.

Типы

Я попытался избежать большинства статически набранных и/или скомпилированных языков, поскольку мой стиль кодирования был, пока не насторожен, также не было ничего близко к стандарту. Возьмите этот код, например:

thing = None
a = 1

if a==1:
    thing = 3
else:
    thing = "Hello world!"

На большинстве низкоуровневых или скомпилированных языков Golang включен, это ужасно табу. Это потому, что Python – это динамически напечатанный язык, так как наиболее интерпретируемые языки. Это потому, что переменные могут удерживать все типы, поэтому они называются динамическими. Когда вы объявляете переменную в Go, пока вы можете объявить переменную без объявления своего типа, поскольку компилятор может отличаться тому, что тип должен быть, тип должен оставаться прежним для продолжительности объема, например:

package main
import "fmt"

func main(){
    things := []string{"one", "two", "three"}

    for i := 0; i<10; i++ {
        fmt.Println(i)
    }

    for _, i := range things {
        fmt.Println(i)
    }
}

Это будет выполнено, но это Потому что переменная Я используется в двух разных областях. Переменная, используемая в петле, была определена в начале объема, вам придется держать его как то, что было такого типа. Например:

package main
import "fmt"

var (
    i int
    things []string
)

func main {
    // This could have been defined like in the previous example
    // but it is better practice to predefine your variables.
    things = []string{"one", "two", "three"}
    for i = 0; i<4; i++{
        fmt.Println(i)
        fmt.Println(things[i])
    }
    // up to here will compile
    // this will not work
    for _, i := range things{ // This doesn't work because i is an integer,
        fmt.Println(i) // not a string.
    }

}

Неиспользованный код

Еще одна вещь, которая пострадала от меня, – это то, что вы не можете иметь неиспользованные переменные в вашем коде Go. Если у вас есть код так:

package main
import "fmt"

func main() {
    var i int
    fmt.Println("Hello world!")
}

Компилятор Go не позволит вам вообще скомпилировать код. Это просто выплюнет ошибку, утверждающую, что существует неиспользуемая переменная. Это для более эффективного выполнения кода, так что ресурсы памяти компьютера и CPU не потрачены впустую определение переменной, которая не используется.

Указатели

Python имеет тенденцию скрывать управление памятью от своих пользователей. Это при попытке сделать его более удобным для начинающих и облегчить развитие. Иди, в то время как более высокий уровень, чем C/C ++, не пытается скрыть память компьютера от вас, разработчика. Это имеет свои взлеты и падения, но самый большой состоит в том, что вы можете поделиться вариабельными значениями в переменных без использования большего количества памяти, что делает программу более эффективной.

Указатели в Go работают точно так же, как они делают в C. Если вы хотите прочитать больше о указателях, здесь Является ли хороший пример в C, который хорошо передает. Самый простой способ подумать о указателях, это то, что они есть, адрес. Они «указывают» на значение в памяти вашего компьютера. Они также действительно хороший способ избежать масштаба. Они позволяют вам передавать глобальную переменную в функцию в качестве параметра и изменяться в функции. Если указатель не используется, функция вне переменной не изменяется. Вот пример из связанной статьи, но переведен в Голанг:

package main
import "fmt"
import "strconv"
// thing is used instead of var because var is a reserved name
func salaryhike(thing *int, b int) {
    *thing = *thing + b
}

func main() {
    var salary int = 95000
    var bonus int = 1500
    fmt.Println("Employee salary: " + strconv.Itoa(salary))
    fmt.Println("Bonus: " + strconv.Itoa(bonus))
    salaryhike(&salary, bonus)
    fmt.Println("Final salary: " + strconv.Itoa(salary))
}

Это позволяет переменной в Главная Область применения, чтобы быть измененным по Salablehike функция.

_GO_ROUTINES и каналы

Одна вещь, которую Python в своей стандартной библиотеке – это система для многопотативной, хотя она не очень интуитивна. Go включает в себя интуитивно понятный способ многопотативных ваших программ и правильно вовлеченные данные между ними. Эти две вещи называются Goroutines и каналами соответственно. Goroutines, называемые COROUTINES, буквально каждый другой язык, простым способом асинхронно выполнять функцию или набор функций. Все, что вам нужно сделать, это поставить ключевое слово идти Перед вызовом функции для начала выполнения функции при запуске выполнения следующей команды. Например:

package main
import "fmt"
import "time"

func helloWorld() {
    fmt.Println("Started secondary routine.")
    time.Sleep(time.Second * 3)
    fmt.Println("Slept for 3 seconds")
}

func main() {
    fmt.Println("Started main routine.")
    go helloWorld()
    time.Sleep(time.Second(time.Second * 4))
    fmt.Println("Finished both threads.")
}

Это будет быстро и эффективно позволить Coroutines в ваших программах. Если вам нужно выполнить ту же функцию несколько раз, все, что вы делаете, это позвоните идти Несколько раз с функцией в цикле вроде так:

package main
import "fmt"
import "time"
import "strconv"

func helloWorld(i int) {
    fmt.Println("Started routine #" + strconv.Itoa(i))
    time.Sleep(time.Second * (i+1))
    fmt.Println("Slept for 3 seconds")
}

func main() {
    fmt.Println("Started main routine.")
    for i:=0; i < 5; i++ {
        go helloWorld(i)
    }
    time.Sleep(time.Second(time.Second * 7))
    fmt.Println("Finished all threads.")
}

Теперь это Действительно Плохая практика, как разработчик, чтобы иметь несколько потоков, записывайте в одну и ту же переменную одновременно. В лучшем случае данные получают немного повреждены, но программа продолжает пошаговать. В худшем случае одна из потоков имеет ошибка сегментации или ошибка в памяти читается и пишет, что потерпела крах всей программы. Перейдите по средствам исправления, предоставляя каналы для воронковых данных между потоками. Когда вы запрашиваете переменную из канала, он получает добавленную древнейшее добавленное значение и продолжает вашу программу. Канал не готов к чтению или записи, выполнение приостановит, пока канал не будет записан на не записать или до тех пор, пока канал не будет готов отправить ваши данные в переменную. Хороший маленький сайт под названием Иди на примере Имеет лучший способ объяснить в основном все на этой странице, и я настоятельно рекомендую вам идти и проверить этот сайт для большего количества прочее, но на данный момент я собираюсь занимать часть сайта об использовании каналов в качестве инструмента, чтобы лучше организовать Goroutines. Сначала я покажу вам свой пример из здесь и объяснить немного лучше после того, как вы посмотрите на него:

package main

import "fmt"
import "time"

func worker(done chan bool) {
    fmt.Println("working...")
    time.Sleep(time.Second)
    fmt.Println("done")

    done <- true
}

func main() {

    done := make(chan bool, 1)
    go worker(done)

    <-done
}

По умолчанию каналы приостановит вашу программу, пока они не имеют данных для чтения, в этом случае, что данные – это логическое значение. Это считается «старым» способом. «Новый» и «рекомендуется» путь (который я сам следую) использует Синхронизация модуль. Вместо того, чтобы иметь отдельный канал для состояния потока, вы передаете указатель на переменную типа синхронизировать Waitgroup на рабочем и отложить команду вагон Сделано () вот так:

package main

import (
    "fmt"
    "strconv"
    "sync"
    "time"
)

func worker(wg *sync.WaitGroup, t int) {
    defer wg.Done()
    fmt.Println(strconv.Itoa(t) + " :Working...")
    time.Sleep(time.Second * time.Duration(int64(t+1)))
    fmt.Println(strconv.Itoa(t) + " :Done.")
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go worker(&wg, i)
    }

    wg.Wait()
}

Вы можете создавать столько же GOROUTINES, сколько вы хотите, независимо от того, какой метод вы используете. В зависимости от вычислительной интенсивности и требований к задаче под рукой, может быть более эффективным использовать несколько Goroutines, или вы можете быть похож на мой разногласий бот и порождать рутину для каждого сервера на бот. Это делает это для двух разных задач. Как библиотека Дискорго Было спроектировано было создание COROUTINE каждый раз, когда запрос был сделан на сервере. Другое использование, которое у меня есть для рутин, связаны с сбором пост и данных. Бот получает случайные посты из Reddit и выплескивает их в канал раздора, который сделал запрос. Другая функция, которая порождает нить для каждого сервера, работает во время последовательности инициализации бота. Для каждого сервера (или «гильдии», поскольку они упоминаются в руководстве), Goroutine будет петлен через каждый текстовый канал, получите его имя и идентификатор, а затем хранит это имя и идентификатор в ОЗУ системы для быстрого доступа Отказ Это сократить задержку, чтобы найти имя канала на соответствующем сервере от около 300 мс до около 1 мс. Даже с рутиной на каждом сервере он по-прежнему занимает около 6,5 секунд, чтобы получить все имена и идентификаторы и хранить их в RAM, но это нагрузки лучше, чем принимать 30 секунд, чтобы построить кеш.

Заключение

Go очень мощно и лиги быстрее, чем на самом деле любой сценарий Python. Теперь пойти заменить все мои сценарии Python и до сих пор позволить мне прототипу в минутах? Нет. Я все равно буду использовать оба, где я вижу посадку, но я буду использовать идти, где скорость имеет сущность, и если система привязана к ресурсам. У обоих языков есть свое место, и в моих проектах они оба моими из моих самых мощных инструментов.

Первоначально опубликовано на моем Блог Отказ

Оригинал: “https://dev.to/chand1012/transisioning-from-python-to-golang-and-why-python-programmers-should-consider-it-4pc9”