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

Go мой шлюз препарат

Как открыть меня на другие языки. Помечено упражнениями, иди, Python, fsharp.

Этот пост впервые появился в моем блоге Отказ

К 2013 году я был длинным разработчиком PHP/JavaScript, когда я впервые начал играть с GO. Сейчас было почти 5 лет, и с тех пор я был сторонником языка. Я был одним из многих программистов, которые пробовали его для примитивов параллелизма, но оставались для его простоты. Сейчас я понял, насколько приятнее жизнь без наследства, а остальные шенаниганы ООП. С другой стороны, иди также дал мне нажатие на эксперимент с еще большему количеству языков. Оказалось, что мой шлюз препарат для изучения программирования языков.

Конечно, я играл с некоторыми языками, такими как Java, Python или Ruby, но, честно говоря, они не предоставили мне ничего, что было бы намного больше, чем было раньше. Я не заинтересовался в писать игры, настольные или мобильные приложения в то время, я был счастлив, как Webweveloper. Для меня Джава чувствовала себя слишком неуклюжему, Ruby чувствовал себя слишком много магии, а Python испытывал недостаток импульса в то время. (Не говоря уже о путанице 2x vs 3.x.) Изучение любого из этих языков было слишком много работы для потенциального усиления. С едой был другой, практически любовь с первого взгляда. Это было так легко учиться и обещано (и выполнено) так сильно, что я даже не мог перестать узнать больше. Однажды я освоил это, хотя я понял, что мои старые языки ООП ощущают многообразные, а мои динамически напечатанные языки чувствуют себя хрупким. Однако я чувствовал, что Python был приятнее читать, чем идти, и это заставило меня взглянуть на дальнейшие языки, в основном новые, такие как ржавчина и эликсир.

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

Чтобы продемонстрировать то, что я имею в виду, добавим несколько решений для простой проблемы, называемой проблемой хэмминга по всему упражнению. Проблема просто находит «расстояние» между двумя строками, означающими количество различных символов.

Выступ

Вот мое решение PHP с 2015 года:

Это на самом деле довольно просто, есть только один, если для проверки длины строки. С другой стороны, есть несколько странных вещей о PHP уже показаны:

  1. Обратите внимание, как str_split имеет символ ‘_’ _ ‘_’ _ ‘_’ _ ‘_’, чтобы отделить детали, но strlen написан как одно слово? Типичный PHP …
  2. Обратите внимание, что array_diff_assoc – довольно конкретная функция. Это показывает, что для изучения очень большой стандартной библиотеки.
  3. Бросание исключения в порядке. Если вы являетесь потребителем этой функции, вам лучше поймать, исключение, брошенное здесь.
  4. Отсутствие типов означает, что вы всегда можете вызвать эту функцию любыми нужными значениями от null к любому типу объект с, до вас. (Да, это может быть необязательно зафиксировано в PHP 7.0+, вид.)

Примечание 1.

Надеюсь, никто не постараюсь получить все, что сделано в одной строке, потому что это может серьезно повредить любому, кто смотрит на него:

Заметка 2.

Можно также написать следующее, используя PHP 7, делая некоторые проблемы уходят. Набрав все еще необязателен, хотя поэтому все еще нет никаких общих гарантий. Учитывая, что это язык сценариев, изменение торможения не нужно очевидно, прежде чем развернуть их, если только ваш тестовый набор не охвачен.

Идти

Мое решение Go с 2017 года:

package hamming

import "errors"

const testVersion = 6

func Distance(a, b string) (int, error) {
    if len(a) != len(b) {
        return -1, errors.New("Lengths of the provided strings are not equal.")
    }

    aBytes := []byte(a)
    bBytes := []byte(b)

    dist := 0
    for i, ch := range aBytes {
        ch2 := bBytes[i]
        if ch != ch2 {
            dist += 1
        }
    }

    return dist, nil
}

Хорошо, что такое вынос здесь?

  1. Это значительно дольше и сложнее, чем решение PHP.
  2. С другой стороны, требуется гораздо меньше предварительных знаний от пользователя, чтобы понять, мы даже не используем стандартную библиотеку. (Быть справедливым, это также можно избежать в PHP)
  3. Там никаких возможно, это решение не может быть написано на одной строке, не нарушая читаемость полностью.
  4. Обратите внимание, как сильная набрав позволяет невозможно вызвать этот метод со странными данными и насколько предсказуемым возвращенные данные есть, за исключением того, что ошибка также может быть Ниль Отказ
  5. Обратите внимание, как ошибки обрабатывались, просто настрая возвращая тип ошибки, «никогда не» бросая что-то неожиданное. (На самом деле есть паника, которая может быть поднята, но это использование отличается от ваших типичных исключений)
  6. Убедитесь, что вы понимаете, что ошибка может быть ноль . Предупреждение: Там будут драконы!
  7. Может быть странно, что функция начинается с заглавной буквы, тогда как другие идентификаторы начинаются с меньшего случая. Это делает код публичным/экспортировать в Go.

Примечание: Я пытался найти более функциональное или значительно прощественное решение Но я не нашел никого.

Обновление: Кабель Benjamin указывал на несколько вопросов с вышеуказанным кодом и предложил лучшую альтернативу. Для описанных вопросов Ознакомьтесь с раздел комментариев Код выглядит следующим образом:

func distance(a, b []byte) (dist int, err error) {
    if len(a) != len(b) {
        return dist, errors.New("length of provided strings is not equal")
    }

    for i := 0; i < len(a); i++ {
        if a[i] != b[i] {
            dist++
        }
    }

    return dist, nil
}

Питон

Мой раствор Python снова с 2015 года:

"""Python distance exercise solution"""

def distance(text_one, text_two):
    """Calculate distance between two strings"""
    count = 0

    for (char1, char2) in zip(text_one, text_two):
        if char1 != char2:
            count += 1

    return count

Забрать:

  1. Цикломатическая сложность здесь немного больше, чем с PHP, даже без проверки ошибок, но я его проще прочитал.
  2. Поддержка Python для кортежей и Zip Функция делает его вид функционально, хотя для Цикл не все, что обычно в ФП.
  3. Нет ничего мешает нам вызывать эту функцию со странными данными.
  4. Там мало, мы можем ожидать от этой функции, которая будет возвращена. Если мы изменим тип возврата в строку, абоненты не будут знать, пока они не получат ошибку времени выполнения.
  5. Мы используем стандартную библиотеку здесь, но Zip чувствует гораздо меньше эзотерики, чем array_diff_assoc был для PHP.

Примечание: Мой Python примерно на уровне продвинутого новичка, Кристоф Шиндлер, похоже, более опытный, его решение читает еще более функционально:

def distance(sequence, other):
    if len(sequence) != len(other):
        raise ValueError('Sequences must be of same length.')

    return sum(1 for a, b in zip(sequence, other) if a!=b)

Дополнительная вынос:

  1. Поднимая ошибку значение, мы можем вызвать еще больше хаос на стороне абонента.

F-Sharp.

И, наконец, вот то же самое, что я писал в F # на этой неделе, имея около 2 дней опыта:

module Hamming

let distance (strand1: string) (strand2: string): int option =
    match strand1.Length, strand2.Length with
    | x, y when x = y ->
        let seq1, seq2 = (List.ofSeq strand1), (List.ofSeq strand2)
        Some(List.fold2 (fun acc a b -> if a = b then acc; else acc + 1) 0 seq1 seq2)
    | _, _ -> None

Что мы можем забрать здесь?

  1. Это немного длиннее, чем решение Python.
  2. Вы можете найти Матч синтаксис странно, но вы можете думать об этом как о Если на стероид на данный момент.
  3. Вы не можете позвонить этой функции с неправильными типами.
  4. Ответ еще более очевиден, чем Go’s, как null Часть здесь не сюрприз, она выражается Опция Тип аннотации.
  5. Мы также используем стандартную библиотеку здесь, но, например, как zip. , Список .fold2. и List.ofseq также чувствовать себя намного меньше эзотерики, чем array_diff_assoc в растворе PHP.

Это не очевидно из приведенного выше примера, но определения явных типов необязательны в F #, если компилятор не сообщает вам, что вам следует предоставить им. Однако типы не являются необязательными, как они находятся в PHP и частично в Python, и, поскольку это скомпилированный язык, есть гораздо меньше места для ошибок. Не имею дело с типовыми в первую очередь, может заставить кодирование заправиться гораздо больше похоже на язык сценариев по сравнению с C #, например. Я только хотел бы, чтобы компилятор был быстрее, намного быстрее, если это возможно. (Компилятор Go чувствует себя около 100 раз быстрее.)

Обновление: Как я уже упоминал выше, я только начал глубже в FP языки FP и F #, вот лучшее решение от комментариев:

let distance s1 s2 = 
  if String.length s1 <> String.length s2 then None
  else
    Seq.zip s1 s2
    |> Seq.sumBy (fun (c1, c2) -> if c1 <> c2 then 1 else 0)
    |> Some

Трудно утверждать, что это очень элегантный раствор.

Выводы

Я думаю, это не удивительно, что я нахожу решение F # лучшего здесь, но, конечно, я не хочу сказать, что F # – лучший язык из четырех. Я даже не думаю, что это справедливо сказать такая вещь в целом. Я также не думаю, что этот пример доказывает, что FP лучше, чем ООП. Очевидно, что эти примеры не дают хорошего понимания того, насколько твердые эти языки должны учиться, насколько это пригоднее, они в диком и многих других важных аспектах языков. Однако они доказывают, по крайней мере, для меня, что стоит учиться другим языкам, как не все языки равны.

Также упражнения это удивительный дилер.

Оригинал: “https://dev.to/peteraba/go-is-my-gateway-drug-5efm”