Компактней чем UTF-16. Где-то натыкался, что одна и та же статья на японской вики в UTF-8 занимает 83Кб, а в UTF-16 144Кб. А составные символы что там, что там будут.
Совместима со стандартным ASCII по представлению. И там, и там байты.
Совместима со стандартным ASCII по кодированию. Нижняя половина таблицы ASCII в UTF-8 выглядит точно так же.
Не зависит от порядка байт. Может быть проблемой при передаче по сети.
Не доступ, а поиск позиции. Доступ по известной позиции тот же O(1)
По той банальной причине, что во всех вменяемых системах юникод.
И UTF-8, и UTF-16 активно используют суррогатные пары.
UTF-32? Окей, 2Х-4Х оверхед по памяти. Но можно.
Вспоминаете про std::string? Там ровно те же проблемы, если вы положили внутрь многобайтную кодировку. Только при этом начисто отсутствуют средства доступа к символам.
Поясню. В С++ у вас вся программа представляет собой один сплошной unsafe блок. Где-то промахнулись с указателем — и всё, приехали. Причём учтите, что с тривиальными ошибками помогают смарт-указатели. С нетривиальными — всё по старому.
Теперь — чем лучше rust конкретно здесь. Возможностью сказать компилятору "конкретно здесь я сделаю сам, а вокруг уж будь добр проконтроллируй ты". Именно поэтому я и говорю, что если, как вы пишете,
оптимизировать оба комплекта программ до упора (возможно, от стандартных функций и структур данных придётся отказаться в пользу самописных или сторонних, лучше подходящих для конкретных задач), проверить, ушла ли разница в скорости, и показать разницу в сложности
у вас получится, по факту, полотнище Си-стайл небезопасного кода. В таком случае на ржавчине код будет длиннее, т.к. подразумевает больше явности. И это было сделано намеренно.
Если же вы имели ввиду написание максимально оптимального кода, но с соблюдением С++-стайл — на С++ будет, скорее всего, длиннее. Почему — инфраструктура написания кастомных контейнеров на С++ всё ещё в зачаточном состоянии. Особенно в области написания типов итераторов.
Да, сравнение с JS напрашивается. Что нравится лично мне:
Прототипная модель на порядок проще. Без дуристики с функциями-конструкторами, Object.create и т.п. Просто создаётся таблица и назначается мета-таблицей нового объекта.
Сильно меньше неявных преобразований непонятно откуда непонятно во что. Если бы отключить неявное преобразование между строками и числами — было бы совсем хорошо.
Значительно проще правила сравнения и истинности. Без феерического идиотизма ==/===. Заодно — отсутствие дуализма null/undefined.
На порядок проще embedding API. Сравниваю по опыту написания нативных аддонов к Node.JS.
Мой личный вывод: в JS накрутили какой-то дикой, неочевидной логики, которая только усложняет жизнь. Особенно много веществ употребили, когда делали реализацию прототипного ООП.
Версии указаны неточно, как можно видеть.
При первичной сборке, менеджер сгенерирует файл, в котором записаны точные версии всех зависимостей и их транзитивных зависимостей. Всех пакетов, как-либо использованных при сборке.
При повторной сборке, если менеджер видит такой лок-файл, он использует версии оттуда. Обновить их список можно отдельной командой. Таким образом, все версии будут зафиксированы до следующего принудительного апдейта — но автоматически, без ручной писанины.
В cargo, где я это наблюдал, обычной практикой является держать такой файл под контролем версий для исполняемых проектов (или любых "конечных") и игнорировать для библиотек.
Это к тому, что общий кэш и общие результаты компиляции, при всей их удобности, не всегда лучшее решение, особенно, в больших проектах.
Я имел ввиду локальный кеш, т.е. репозитории втягиваются в подпапки какой-то папки в домашнем каталоге пользователя. Если репозиторий уже есть — его никто не тянет повторно.
В Meson с этим строго: все зависимости, включая транзитивные, должны явно прописываться в корневом проекте
Вот этого и не хочется совершенно. Разве Meson не умеет писать lock-файл с конкретными версиями зависимостей? Этот подход как раз и придумали чтобы иметь мягкое задание версий зависимостей и при этом воспроизводимые билды.
Meson смотрел. Судя по доке, врапперы нельзя накладывать на репозитории исходников, только на архивы.
Ну а предложенный вами способ можно реализовать практически в любой системе сборки, менеджер пакетов для этого не нужен. Интересовала поддержка git как полноценного источника:
Выкачивание в общую папку кеша
Учёт случаев, когда один и тот же репозиторий запрашивается транзитивно несколькими зависимостями
Автоматическая сборка и предоставление её результатов зависимым пакетам — конкретно папки с публичными заголовочными файлами плюс артефакты сборки.
При этом вполне можно было бы требовать, чтобы для такого источника было отдельное описание — какая версия какой ветке/коммиту соответствует. К сожалению, ни Conan, ни Meson не поддерживают такой кейз — по крайней мере в простом виде.
Репозитории Git не должны быть ни основным ни, тем более, единственным источником зависимостей. Но такая возможность должна быть, тем более в С++ мире, где разброд и шатания.
Увы, у Conan есть одна фундаментальная проблема — он работает исключительно с репозиториями пакетов. Т.е. нельзя использовать проект на Github или в любом другом хранилище кода как зависимость. Объявлять локальные папки как зависимости вроде можно, но как минимум заморочно. Разработчики аргументируют это тем, что Conan умеет разрешать конфликты версий и хранить бинарные артефакты.
Мне не нравятся оба варианта, по нескольким причинам
Завязано на операторы вывода в поток
Требуется явно плодить объекты.
Энергичное вычисление всего, что отправляется в лог. Даже если сообщение будет отфильтровано по уровню.
Почему мне не нравятся большинство нынешних библиотек журналирования — они как минимум некомпактные, а как максимум монструозны. И рассчитаны на то, что только Их Высочеств будут использовать по всему проекту. Надо скрестить несколько проектов, использующих разные библиотеки журналирования — развлекайтесь с их "скрещиванием".
Disclaimer: претензия ниже не к автору и не к переводчику.
Как по мне, этот механизм как был недоделан, так и остался. Попытка навести марафет на трупик errno.
Увы, я потихоньку разувериваюсь. Некоторые хронические болячки либо не решаются, либо решаются с адскими задержками. Зато накидывают всякой ерунды — вроде зета-функции Римана. Вот самое место в стандарте! Проблема же миграции на другие языки часто в том, что С++ несовместим ни с кем кроме С++ — причём часто только своим диалектом.
Несколько возможных причин, а может и все вместе
Не доступ, а поиск позиции. Доступ по известной позиции тот же O(1)
По той банальной причине, что во всех вменяемых системах юникод.
И UTF-8, и UTF-16 активно используют суррогатные пары.
UTF-32? Окей, 2Х-4Х оверхед по памяти. Но можно.
Вспоминаете про std::string? Там ровно те же проблемы, если вы положили внутрь многобайтную кодировку. Только при этом начисто отсутствуют средства доступа к символам.
Поясню. В С++ у вас вся программа представляет собой один сплошной unsafe блок. Где-то промахнулись с указателем — и всё, приехали. Причём учтите, что с тривиальными ошибками помогают смарт-указатели. С нетривиальными — всё по старому.
Теперь — чем лучше rust конкретно здесь. Возможностью сказать компилятору "конкретно здесь я сделаю сам, а вокруг уж будь добр проконтроллируй ты". Именно поэтому я и говорю, что если, как вы пишете,
у вас получится, по факту, полотнище Си-стайл небезопасного кода. В таком случае на ржавчине код будет длиннее, т.к. подразумевает больше явности. И это было сделано намеренно.
Если же вы имели ввиду написание максимально оптимального кода, но с соблюдением С++-стайл — на С++ будет, скорее всего, длиннее. Почему — инфраструктура написания кастомных контейнеров на С++ всё ещё в зачаточном состоянии. Особенно в области написания типов итераторов.
Да, сравнение с JS напрашивается. Что нравится лично мне:
==/===. Заодно — отсутствие дуализмаnull/undefined.Мой личный вывод: в JS накрутили какой-то дикой, неочевидной логики, которая только усложняет жизнь. Особенно много веществ употребили, когда делали реализацию прототипного ООП.
Вам это приходится делать прямо в условной бизнес-логике, "по ходу пьесы"?
Если вам нужен прозрачный интероп с ОС, всегда можно
https://doc.rust-lang.org/std/ffi/struct.OsString.html и https://doc.rust-lang.org/std/ffi/struct.OsStr.html
Если вам не хватает
std::string/std::wstring, то зря — принудительная юникодная локаль для всех стандартных строк это хорошо. Как вспомню танцы с ними на Windows — так вздрогну.Не вижу смысла. Тогда "крестики" выиграют автоматом, т.к. на расте придётся обложиться ансэйфом. Который не лаконичен намеренно.
Побуду занудой
https://doc.rust-lang.org/std/primitive.slice.html#method.split_at_mut
И никаких мучений с
Вопрос к аудитории. Приложения на UWP хоть кто-то использует в природе? У меня стабильное впечатление "технология ради технологии".
Пусть у нас есть конфиг с зависимостями
Версии указаны неточно, как можно видеть.
При первичной сборке, менеджер сгенерирует файл, в котором записаны точные версии всех зависимостей и их транзитивных зависимостей. Всех пакетов, как-либо использованных при сборке.
При повторной сборке, если менеджер видит такой лок-файл, он использует версии оттуда. Обновить их список можно отдельной командой. Таким образом, все версии будут зафиксированы до следующего принудительного апдейта — но автоматически, без ручной писанины.
В cargo, где я это наблюдал, обычной практикой является держать такой файл под контролем версий для исполняемых проектов (или любых "конечных") и игнорировать для библиотек.
Я имел ввиду локальный кеш, т.е. репозитории втягиваются в подпапки какой-то папки в домашнем каталоге пользователя. Если репозиторий уже есть — его никто не тянет повторно.
Вот этого и не хочется совершенно. Разве Meson не умеет писать lock-файл с конкретными версиями зависимостей? Этот подход как раз и придумали чтобы иметь мягкое задание версий зависимостей и при этом воспроизводимые билды.
Meson смотрел. Судя по доке, врапперы нельзя накладывать на репозитории исходников, только на архивы.
Ну а предложенный вами способ можно реализовать практически в любой системе сборки, менеджер пакетов для этого не нужен. Интересовала поддержка git как полноценного источника:
При этом вполне можно было бы требовать, чтобы для такого источника было отдельное описание — какая версия какой ветке/коммиту соответствует. К сожалению, ни Conan, ни Meson не поддерживают такой кейз — по крайней мере в простом виде.
Репозитории Git не должны быть ни основным ни, тем более, единственным источником зависимостей. Но такая возможность должна быть, тем более в С++ мире, где разброд и шатания.
Увы, у Conan есть одна фундаментальная проблема — он работает исключительно с репозиториями пакетов. Т.е. нельзя использовать проект на Github или в любом другом хранилище кода как зависимость. Объявлять локальные папки как зависимости вроде можно, но как минимум заморочно. Разработчики аргументируют это тем, что Conan умеет разрешать конфликты версий и хранить бинарные артефакты.
Моё уважение вашим коллегам из другого отдела за то, что они об этом подумали. Особенно если интерфейс журналирования компактный и понятный.
Мне не нравятся оба варианта, по нескольким причинам
Почему мне не нравятся большинство нынешних библиотек журналирования — они как минимум некомпактные, а как максимум монструозны. И рассчитаны на то, что только Их Высочеств будут использовать по всему проекту. Надо скрестить несколько проектов, использующих разные библиотеки журналирования — развлекайтесь с их "скрещиванием".
Мои попытки причесать собственный велосипед: https://github.com/target-san/log_facade.
Disclaimer: претензия ниже не к автору и не к переводчику.
Как по мне, этот механизм как был недоделан, так и остался. Попытка навести марафет на трупик errno.
Увы, я потихоньку разувериваюсь. Некоторые хронические болячки либо не решаются, либо решаются с адскими задержками. Зато накидывают всякой ерунды — вроде зета-функции Римана. Вот самое место в стандарте! Проблема же миграции на другие языки часто в том, что С++ несовместим ни с кем кроме С++ — причём часто только своим диалектом.
Fixed