LINUX.ORG.RU

Читабельность Rust, C++ и Go

 , , , ,


0

7

Go:

    func typeList(arch *TFile,
      offset uint32, parseDecl bool) []BStr {

C++:

    std::vector<std::string> typeList(TFile* arch,
        off_t offset, bool parseDecl) {

Rust:

    fn typeList<'a>(arch: &'a TFile<'a>,
      offset: u32, parseDecl: bool) -> Vec<&'a bstr> {

как поддерживать код, если он не читаем?



Последнее исправление: clover (всего исправлений: 1)

И что за хрень ты написал в примере?

Deleted
()

Когда-нибудь уже ЛОР научится парсить растокод? Или нужно подождать пока ИИ запилят?

anonymous
()

Ты написал не тот же самый код для раста. В с++ ты вернул аллоцированные на куче строки, а в расте венул указатели на содержимое памяти TFile. Эквивалетный код будет:

fn typeList(arch: &TFile, offset: u32, parseDecl: bool) -> Vec<String> {
pftBest ★★★★
()

То есть, ты решил сравнить объект со ссылкой, для которой пришлось указать время жизни? Интересно, и что из них эффективнее?

dave ★★★★★
()

как поддерживать код, если он не читаем?
Go:
C++:
Rust:

Сравниваешь с Python, и прям аж сам себе завидуешь:

def typeList(arch, offset, parseDecl):

Manhunt ★★★★★
()
Ответ на: комментарий от anonymous

не надо код поддерживать :-) написал и забыл :-)

Вротонли подъехали

Siado ★★★★★
()
Ответ на: комментарий от pftBest

Ты написал не тот же самый код для раста.

Да и пофиг. Читабельность у Раста на самом деле хуже, чем в среднем по больнице.

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Сравниваешь с Python, и прям аж сам себе завидуешь:

Нетипизированное убожество.

anonymous
()
Ответ на: комментарий от O02eg

не ясно, что скармливать этой функции и чего от неё ожидать.

def typeList(arch: TFile, offset: int, parseDecl: bool) -> list:

А для самых неспособных тайпхинтинг через комменты завезли.

entefeed ☆☆☆
()
Последнее исправление: entefeed (всего исправлений: 1)
Ответ на: комментарий от Manhunt

Сравниваешь с Python, и прям аж сам себе завидуешь:

def typeList(arch, offset, parseDecl):

Чтобы с питоном сравнение было корректно, надо так:

def typeList(arch, offset, parseDecl):
    assert type(arch) == TFile, "arch Not TFile"
    assert type(offset) == uint32, "offset Not uint32"
    assert type(parseDecl) == bool, "parseDecl Not bool"
    
    ...

Siado ★★★★★
()
Ответ на: комментарий от dave

То есть, ты решил сравнить объект со ссылкой, для которой пришлось указать время жизни? Интересно, и что из них эффективнее?

Ой, да пожалуйста, вот тебе код со ссылками:

    std::vector<std::string_view> typeList(TFile* arch,
        off_t offset, bool parseDecl) {

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)

Вот спроси у неграмотного как поддерживать текст на простом привычном русском языке - он задаст такой же вопрос.

Да никак. Это не для тебя, ибо ты неграмотен - отсюда и проблемы. Либо учиться, либо валить в деревню коров пасти - подальше от таких сложных дьявольских машин.

slovazap ★★★★★
()
Ответ на: комментарий от Manhunt

А если файлов будет не один а два, то по сигнатуре функции не будет видно на память кторого из них ссылается твоя строка.

pftBest ★★★★
()
Ответ на: комментарий от Siado

Чтобы с питоном сравнение было корректно, надо так:

Так тебе нужен код, который совершает полезную работу и легко читается? Или код, который наполовину состоит из бессмысленного мусора (да-да, это я про принудительное описание типов — словно компилятор убогий и не может их сам вывести) и завален каракулями?

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от pftBest

А если файлов будет не один а два

и нужно вернуть вектор ссылок, в котором могут быть ссылки и на содержимое первого файла, и на содержимое второго, как это в Rust-е записать? (вопрос без сарказма)

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Просто дать обоим файлам одинаковое ограничение на время жизни:

fn foo<'a>(file1: &'a File, file2: &'a File) -> Vec<&'a str> {
    unimplemented!()
}

Так как лайфтамы поддерживают subtyping, то это будет то же самое как если ты явно это запишешь (но никто так писать конечно не будет):

fn bar<'a, 'b: 'a, 'c: 'a>(file1: &'b File, file2: &'c File) -> Vec<&'a str> {
    unimplemented!()
}

pftBest ★★★★
()
Ответ на: комментарий от pftBest

А если файлов будет не один а два, то по сигнатуре функции не будет видно на память которого из них ссылается твоя строка.

После запихивания в сигнатуру сведений о временах жизни, всё равно останется куча вопросов о семантике функции, на которые сигнатура ответа не даёт. Так что в любом случае придётся обращаться к документации или вчитываться код реализации.

Явная спецификация лайфтамов позволяет компилятору гарантировать memory safety, но вот в плане читабельности от лайфтаймов только проблемы.

Manhunt ★★★★★
()

Учить язык. Тут в коментах уже писали варианты(как минимум для раста), как сделать все корректно и читабельно.

Aswed ★★★★★
()

Вот, сразу видно, что сишку делали для людей, потом щупальцы поработали, но основа плюсов все же человеческая. Го - это тоже сишка, но с легкой придурью. Раст - сделан щупальцами для щупалец...

anonymous
()
Ответ на: комментарий от eao197

Нет, не помножили, ты ведь спросил что будет если они чередуются, значит и не следует удалять не первый не второй файл пока ссылочки живут.

pftBest ★★★★
()
Последнее исправление: pftBest (всего исправлений: 1)
Ответ на: комментарий от Manhunt

в плане читабельности от лайфтаймов только проблемы.

А вот интересно написать плагин для вима, чтобы скрывал все лайфтаймы и показывал только по хоткею.

anonymous
()
Ответ на: комментарий от pftBest

Просто дать обоим файлам одинаковое ограничение на время жизни

Другими словами, Rust так же не способен удовлетворить ваши же условия: «А если файлов будет не один а два, то по сигнатуре функции не будет видно на память кторого из них ссылается твоя строка.»

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

сишку делали для людей

Это сишка-то с её повсеместным UB сделана «для людей»?!

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Если код хорошо подсветить, то дополнительная информация в сигнатуре не будет существенно вредить читабельности, у нас ведь не секта Роба Пайка всё-таки.

Softwayer ★★
()
Ответ на: комментарий от anonymous

Го - это тоже сишка, но с легкой придурью.

Наоборот же, подлеченная от многих идиосинкразий.

anonymous
()
Ответ на: комментарий от eao197

Именно что способен, если файлов два и сигнатура такая:

fn baz<'a>(file1: &'a File, file2: &File) -> Vec<&'a str> {
    unimplemented!()
}
Я точно знаю что могу спокойно удалить file2 пока вектор еще живет, потому что его память уже не используется.

pftBest ★★★★
()
Ответ на: комментарий от eao197

Распишу тогда. Результат по ссылкам будет валиден до минимального времени жизни обоих файлов

dave ★★★★★
()
Ответ на: комментарий от dave

В принципе да. Но давайте взглянем на условие pftBest-а:

А если файлов будет не один а два, то по сигнатуре функции не будет видно на память кторого из них ссылается твоя строка.

Из предложенного варианта (как вами, так и pftBest-а) будет видно только то, что строки должны иметь те же самые времена жизни, что и файлы (т.е. строки не должны пережить файлы из которых взяты). Но по сигнатуре функции не будет видно, на память которого ссылается строка.

eao197 ★★★★★
()
Ответ на: комментарий от pftBest

Вы же на этот вопрос пытались ответить:

и нужно вернуть вектор ссылок, в котором могут быть ссылки и на содержимое первого файла, и на содержимое второго, как это в Rust-е записать?

Так что ваш пример не является иллюстрацией ответа на него.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

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

pftBest ★★★★
()

Читабельность C++ зависит от кривизны рук программера

typedef TStrings std::vector<std::string>

TStrings typeList(TFile* arch, off_t offset, bool parseDecl)
{
...
}

Kroz ★★★★★
()
Ответ на: комментарий от pftBest

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

Вообще-то тип у элементов вектора будет одинаковый — это будут строки.

Попытка навесить на тип еще и лайфтаймы — это интересный эксперимент, но последствия его как-то вызывают недоумения. Допустим, у вас функция typeList вызывается внутри функции makeTypeList с такой сигнатурой:

fn makeTypeList<'a, 'b>(f: &'a File, g: &'b File) {...}
сможете ли вы внутри makeTypeList вызвать typeList, с такой сигнатурой:
fn typeList<'a>(f1: &'a File, f2: &'a File) -> Vec<'a Str> {...}
?

Ведь у f и g разные типы?

PS. Пока писал пример задолбался символы пунктуации набирать в примерах кода.

eao197 ★★★★★
()

Если часто используешь std::vector<std::string> то сделай алиас:

using string_vector = std::vector<std::string>;

string_vector typeList(TFile* arch, 
                       off_t offset, 
                       bool parseDecl) {
}

KennyMinigun ★★★★★
()
Ответ на: комментарий от eao197

На 'a и 'b из makeTypeList будет наложено ограничение. Они не должны жить меньше чем 'a из typeList.

Пока писал пример задолбался символы пунктуации набирать в примерах кода.

Потому что редкий случай. Lifetime elision обычно позволяет писать без ВЖ.

red75prim ★★★
()
Последнее исправление: red75prim (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

Если часто используешь std::vector<std::string> то сделай алиас:

Тут достаточно using.

anonymous
()
Ответ на: комментарий от eao197

Имменно так как вы записали можно: https://play.rust-lang.org/?gist=450a1bbd61f57e995574ba1f397a753b&version...

Можно потому что компилятор знает что в теле функции makeTypeList оба файла всегда живы.

Проблемы начнутся когда захочешь вернуть результат работы typeList из функции makeTypeList

pftBest ★★★★
()
Ответ на: комментарий от eao197

Похоже, что вы с pftBest по разному поняли, что имел в виду pftBest

dave ★★★★★
()
Ответ на: комментарий от pftBest

Проблемы начнутся когда захочешь вернуть результат работы typeList из функции makeTypeList

Ну вот это и интересует. Как мне кажется, в Rust-е сейчас это не решается. Или решается?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Для принятия решения можно или нельзя так делать, компилятор анализирует только сигнатуры функции, а не их содержимое(потому что в общем случае это нерешаемая задача).

Человек решает что он хочет написать в сигнатуре. Если автор typeList написал в сигнатуре что она возвращает строки из обоих файлов (дал обоим файлам 'a), то у того кто пишет makeTypeList есть два варианта, или он тоже связывает время жизни двух файлов, или перемещает строки на кучу, как в примере на C++.

pftBest ★★★★
()
Последнее исправление: pftBest (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.