1. Go / Говнокод #28193

    −2

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    package main
     
    func main() {
        var str = "Hello World"
        var length = len([]rune(str))
        println("Length of the string is :", length)
    }

    String Length in Golang

    To get the length of a String in Go programming, convert the string to array of runes, and pass this array to len() function.

    Запостил: 3_dar, 26 Мая 2022

    Комментарии (93) RSS

    • кто такие руны?

      инь, как тебе го? Выучить советуешь?

      У меня есть пара говнотулов на няшной, статически слинкованных. Думаю их на го переписать, а то хипстота в няшную не может. Стоит ли?
      Ответить
      • Почему не C++?
        Ответить
        • Потому что хипстота даже в нящную не может, не то, что в кресты

          Крестотул у меня тоже е, но я его пок ане буду трогаць
          Ответить
          • В няшной вообще нихуя нет. А на крестах можно просто написать. Там хотя бы строки есть.
            Ответить
            • Угу, это одна из причин, по которой я стараюсь писать на кресте
              Другая причина это коллекции, и еще деструкторы. Вручную ебаться не очень прикольно, но увы
              Ответить
      • Ты такой убогий, что даже в "Готику" не играл? А в "Райзена"? Но там правда рун нет, только печати.
        Ответить
      • хипсторы умрут
        Ответить
      • Разве не моднее сразу переписать на раст? Или фондов на освоение хватит и на то и на другое?

        Кодопойнты небось, всё не как у сапиенсов.
        Ответить
    • где-то в параллельном мире обезьян сажают в россиянники
      Ответить
      • А какая разнца?
        Ты тварь тупая, в политоту!
        Ответить
    • не пезди
      func main() {
      	foo := "foo"
      	fmt.Printf("%d", len(foo)) // 3
      }
      Ответить
      • У тебя foo — это не string. Попробуй написать функцию, принимающую строку и напечатать её длину.
        Ответить
        • лолшто?? а что же это?

          >попробуй
          func foo(s string) {
          	println(len(s)) //4
          }
          
          func main() {
          	foo("FFFF")
          }


          Я и твою программу починив
          func main() {
          	var str = "Hello World"
          	var length = len(str)
          	println("Length of the string is :", length) // Length of the string is : 11
          }
          Ответить
          • так что конвернуть в массив буков и посмотреть его размер это правельно
            Ответить
        • на самом деле я тебя наеабл конечно


          Это размер в байтах а не буквах рунах
          ты совершенно прав


          я тебе напиздел понимаешь НАПИЗДЮНЬКАЛ наебал тебя блять ты понимаешь я СОВРАЛ нахуй я сказал тебе неправду
          Ответить
        • иными словами len("хуй") будет шесть, потому что УТФ-8
          Ответить
          • А вообще можно и с рунами проебаться. Пример запостить не могу, потому что пидар сракер, но: комбинируемые глифы. К примеру новые эмодзи, которым можно красить кожу и выбирать причёску.
            Ответить
            • Я пишу программы для серьезных белых людей. Азиатские закорючки и смайлы для подростков меня не ебут

              Руна это просто кодпоинт в юникоде размером кажется что 32 бита же? тоесть количество памяти у массива рун может быть больше чем у строки утф8 (а у массива еще и размер же)

              Но вообще Иню прав в том, что функцию len писали горбатые колоеды
              Array: the number of elements in v.
               Pointer to array: the number of elements in *v (even if v is nil).
               Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
               String: the number of bytes in v. // <-------- ДА ПОЧЕМУ БЛЯДЬ?? Чтобы в буфер записать и передать по сети что ли? 
               Channel: the number of elements queued (unread) in the channel buffer;
                        if v is nil, len(v) is zero
              Ответить
              • На тебе, строка для белых людей, "Ёлочка". 7 рун.
                Ответить
                • да ну?
                  newYearTree := []rune("Ёлочка") 
                  	println(len(newYearTree)) //6
                  	fmt.Printf("%c", newYearTree[0]) //Ё
                  	println(newYearTree[0]) // 1025

                  https://unicode.scarfboy.com/?s=U%2B0401 (401 по программячи 1025)


                  А вообще Ё не нужно
                  Мы не беларусы


                  зы: а вот со всякими лигатурами наверное и верно отсосать можно
                  Ответить
                  • Блядь, да не "Ё", а "Ё", разницы не видишь что-ли?

                    https://i.imgur.com/8hzdsuV.png
                    Ответить
                    • А вот теперь ты прав

                      Это руна 1045 (е) плюс руна 776 (диатезис или как-то так)
                      https://www.compart.com/en/unicode/U+0308

                      ,но руны тут не виноваты: по правилам уняк-кода это ДВА различных кодпоинта
                      да?
                      Ответить
                      • Да. Обычно они не используются, потому что всякие Ё и Ü — отдельные буквы а не Е/U с точечками. Могут использоваться в словах типа cöoperation всякими блюстителями орфографии, как и знаки ударения. Но встречались мне api, которые упорно нормализовали в NFD вместо NFC.

                        Вообще — юникод нужно обрабатывать функциями для юникода. Потому что есть вообще 3 метрики — code units, code points и знакоместа, которые я не помню как называются. Для нормальных людей интересно обычно последнее.
                        Ответить
                        • типа https://pkg.go.dev/unicode ?
                          я ниибу правда есть ли тамс длина


                          > Ё и Ü — отдельные буквы а не Е/U с точечками.
                          Это зависит от языка КМК

                          В английском ты можешь написать "Cafe" вместо "Café", это не будет ошибкой.
                          В нидерландском "een" это неопределенный артикль, а "één" это один (число) и скорее всего путать их не нужно

                          В русском ёжик и ежик ничем не отличаются, а у беларусов нельзя вместо "вёскi" (деревни) написать "вескi" -- это так же будет ошибкой

                          ps: доречи, кириллическая i (укр и бел) и латинская i -- разные кодпоинты


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

                          то есть когда я говорю "в слове хуй три буквы" я говорю о знакоместах?
                          Ответить
                          • > Это зависит от языка КМК
                            Да, я имел в виду русский и немецкий. В других языкам могут быть как отдельные элементы для изменения букв, так и отдельные буквы, и свои правила использования этого всего.

                            > то есть когда я говорю "в слове хуй три буквы" я говорю о знакоместах?
                            Ну тебе же насрать, что перед "х" вставлен LTR маркер, чтобы арабы правильно слово видели, а между буквами какой-нибудь Joiner, чтобы слово не пидорасилось переносом? Значит о знакоместах.
                            Ответить
                            • а есть еще жопка с лигатурами

                              вот например немцы "ss" пишут как ẞ (а швеййарцы -- нет)
                              Это одна буква или две?

                              У голландцев есть звук "ij" (ай или эй в зависимости от региона) и для него в теории тоже есть отдельная буква но почти не используется
                              Ответить
                              • В танковой дивизии дедушка служил
                                В далекой России порядок наводил.
                                Ни один комиссар от него не удрал
                                Дед к большевикам жалости не знал.

                                Дед мой был штурмфюрер ẞ,
                                Дед мой был штурмфюрер ẞ,
                                Дед мой был штурмфюрер ẞ,
                                Дед Штурмфюрер, Штурмфюрер ẞ.
                                Ответить
                                • SS так писать ненадо: эсцет это для сдвоенной С (которая читается как С а не как З) а SS это аббривеатура Schutzstaffel.

                                  А вот песня про дедушку есть
                                  https://youtu.be/omfaIvqB7U0?t=25
                                  Ответить
                        • Программист: одна буква -- один байт
                          Жиза: "Ελλάδα это Греция"
                          Программист: для блядь, ладно. Одна буква -- один кодпоинт размером 4 байта
                          Жиза: "Ё"
                          Программист: буду проституткой
                          Ответить
                    • короче уняккод ничем не лучше утфа: ты не знаешь скока буков пока не прочитаеш строку и хуй ты за O(1) скажеш
                      можно тока за O(N)

                      как называлась та сишная либа которая всё это умела?
                      Ответить
                      • Есть тяжеленная ICU, которая умеет в кластеры графем и прочее юникодное извращение. Или речь о чём-то более лёгком? Так-то декодер UTF8 в UTF32/UCS4 можно реализовать буквально одним экраном кода.
                        Ответить
                        • Ещё есть harfbuzz для более сложной задачи — рендеринга. Она разбирает текст на основные символы и акценты, загружает метрику из шрифта и возвращает массив относительных координат, по которым будут рендериться глифы.

                          Подсчёт длины строки в пикселях становится нетривиальной задачей. Это не в ДОСе длину строки умножить на восемь...
                          Ответить
                    • Кстати, ты же вкурсе подхода рустишки?

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

                      Хочешь индексировать -- ну конвертни в байты (если все символы семибитные) и ебаш массив и слайс

                      А если хочешь нырнуть в говно, то вот
                      https://crates.io/crates/unicode-segmentation

                      Iterators which split strings on Grapheme Cluster or Word boundaries.

                      Так что рустишкам сразу сказали, что деда мороза не существует.
                      Все остальные языки едят говно в этом вопросе и лгут пользователю, и между нами -- не далеко ушли от сишки с char[], разве что чар у них побольше
                      Ответить
                      • Круто. Если бы все так делали сразу, не возникало бы костылей типа «не используйте нелатинские буквы в именах».

                        Удобно, что сразу графемы. Ничего не оторвёт при переносе.

                        А если всё-таки надо графему разбить на кодпоинты (например, я пишу рендер), то как это лучше сделать?
                        Ответить
                      • Я кстати малость напиздюнькал

                        Тип char всё таки есть, и это примерно Unicode Scalar (назовём его "буква")
                        Он занимает 4 байта, но строка не состоит из чаров
                        Строка состоит из байт

                        Поскольку невозможно получить в общем случае символ за O(1), а индексация должна работать за O(1), то высосать чары из строки можно только через итератор

                        Это будет O(N), но от итератора ты другого и не ожидаешь

                        То есть это как в плюсах: вектор индексируется, а лист -- нет.

                        Строка поддерживает слайсинг кстати, но если ты попадешь в середину UTF-8 (строки там всегдла UTF-8) то получишь паник
                        Ответить
      • традиционно спиздуль не разобравшись
        Ответить
    • А вот еще про го

      Захватывает кложа что-то по значению или по ссылке? Ответ на этот вопрос должен быть очевиден любому программисту, потому вы без труда скажете, что выведет эта программа
      func main() {
      	for i := 1; i < 100; i++ {
      		go func() {
      			println(i)
      		}()
      	}
      	time.Sleep(time.Second * 2)
      }

      Ответ будет через час
      Ответить
      • Ну как, час прошел?
        Ответить
        • Да

          Знаешь ответ, или рассказать?
          Ответить
          • Рассказать
            Ответить
            • В цикле i изменяется на каждую итерацию. Могли бы и новую переменную делать, но не делают.

              Захват кложей свободных переменных происходит по ссылке в данном случае.
              Утверждается, что эвристика следующая

              // capturevars is called in a separate phase after all typechecking is done.
              // It decides whether each variable captured by a closure should be captured
              // by value or by reference.
              // We use value capturing for values <= 128 bytes that are never reassigned
              // after capturing (effectively constant).

              https://eli.thegreenplace.net/2019/go-internals-capturing-loop-variables-in-closures/

              Поскольку i меняется, то её и хватают по ссылке, и все горутины сидят с одной переменной, которая быстро превращается в 100.

              Првильно её скопировать, тогда её захватят по значению, и будет заебс
              for i := 1; i < 100; i++ {
                              i := i // да, такой вот тупой код
              		go func() {
              			println(i)
              		}()
              	}

              Еще более правильно наверное никогда не хватать ничего в кложах, и всегда явно передавать переменную так как там ты можешь управлять способом передачи

              for i := 1; i < 100; i++ {
              		go func(int i) { //тут хочешь по значению, хочешь по указателю
              			println(i)
              		}(i)
              	}
              Ответить
    • кое-что о петухах
      https://twitter.com/i/status/1575831527619203073
      Ответить
    • Или вот например про го тоже неожиданно смешное

      Во всех языках (даже в С++) this это указатель. А в Go это просто аргумент, который можно передать.. по значению

      Это не значит, что он скопируется (если ты его не изеняешь -- то компилятор может сделать конст реф) но семантикка такая, что метод получает копию

      Это очень смешно))))
      Ответить
      • В питухоне тоже просто аргумент. Который передаётся по значению. Просто там ссылочная семантика у переменных.

        А в Крестах планируется добавить возможность указывать this-аргумент. Ему можно быдет указывать разные const/volatile и прочую питушню, как обычному аргументу, а не после закрывающей скобки, как сейчас. А ещё его можно будет сделать не указателем, а ссылкой, чтобы разным указателефобал лучше спалось. А ещё его можно сделать значением, тогда при вызове метода он будет оперировать на копии объекта....
        Ответить
        • Страус в книжке рефликсировал, что дескать надо было делать референсом, но моя согласен, что заебатее было бы
          bool Petookh::Jajtso(moja const &Petuh) {
             return moja.m_jajtso;
          }


          Так вот собccно говнари могут делать так
          type counter struct {
          	i int
          }
          
          func (c counter) inc() {
          	c.i++
          }
          func (c *counter) incNoBagor() {
          	c.i++
          }
          
          func main() {
          	c := counter{}
          	c.inc()
          	c.inc()
          	c.inc()
          	println(c.i) // 0
          	c.incNoBagor()
          	println(c.i) // 1
          }


          Причем передача по значению это еще такой способ сказать "хочу конст".

          Казалось бы пидорство -- копировать говно заради чтобы случайно не поменять его, но на этот случай у гавнарей есть во-первых агрессивный инлайнинг
          .\main.go:7:6: can inline counter.inc with cost 4 as: method(counter) func() { c.i += 1 }
          .\main.go:10:6: can inline (*counter).incNoBagor with cost 4 as: method(*counter) func() { c.i += 1 }

          А во-вторых анализ убегателя достаточно жирную пиздень всё равно покладет в кучу, и будет работать с нею по ссылке

          type counter struct {
          	i       int
          	padding [4096 * 4096]byte
          }
          
          //go:noinline
          func (c counter) inc() {
          	print(c.i)
          }
          .\main.go:14:2: moved to heap: c
          Ответить
          • > Страус в книжке рефликсировал, что дескать надо было делать референсом, но моя согласен, что заебатее было бы

            Можно радоваться, всего-то годик до С++23 осталось подождать: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html
            Можно писать:
            void Pituh::crow(this Pituh& kukarek)
            {
                 kukarek.say("cock-a-doodle-doo");
            } 
            // или
            Pituh Pituh::as_food(this Pituh food)
            {
                return food.kill().prepare().cook();
            }


            Бонус: скоро можно будет в коде писать
            [[assume(gender == Gender.Male)]];
            Ответить
            • А можно ли будет написать
              void Pituh::lol(this Pituh **kukarek) {
              *this = null;

              ?

              >assume
              без него не скомпилируется?

              Алсо, джендер в 2023 не дикретен
              И вообще это социальный коснтрцукт
              Ответить
              • Технически можно будет. Но работать это не будет. В смысле написать pituh.lol() не получится. Но можно будет:
                Pituh* pituh = new Pituh;
                (&Pituh::lol)(&pituh); // LOL, pamyat' utekla

                Потому что авторам этого пропозала надоело ебаться с функциями-членами и их ограничениями, и они захотели сделать свои новые функции — статичными с сахарком, чтобы их можно было вызывать через ".".

                > без него не скомпилируется?
                Скомпилируется. А если ты напимал одно, а окозалось что в реальности это выражение ложно — получишь UB.

                В реальности это нужно для того, чтобы подсказывать кобелятору, как лучше оптимизировать. К примеру, у меня есть код, который реализует правильное деление с остатком, а не интеловскую хуйню. Как результат, там внутре условие, которое для отрицательных чисел делает хитрые манипуляции. Если я знаю, что какая-то функция использует этот код, и что значение будет всегда положительным, я могу написать [[assume( x > 0 )]] и кобелятор выкинет проверку на отрицательность и весь экстра код, оставив тупо один IDIV из всего кода.
                Ответить
                • Понятно, то есть это например
                  int foo(int i) { //мамой клянуть функция не вернет отрицательного числа
                  }

                  А можно специальным ключом комплятора вставить проверку в рантайме для дебага чтобы там реально вылетала ошибка если вернется не то,что обещано?
                  Ответить
                  • assert ?
                    Ответить
                    • да

                      можно assume превратить в assert в дебажной бсорке, шоп вместо UB иметь фаст фейл?
                      Ответить
                      • Как-то так
                        #define assumert(EXPR) \
                            assert(EXPR);\
                            [[assume(EXPR)]]
                        В скобки аргумент заключать (обычный хак для безопасности) нельзя, потому что это слегка меняет поведение assume. Переключателя в компиляторе не будет, потому что assume не вычисляет аргументы: [[assume(++i > 42)]] не изменит значение i, и вообще, компилято имеет право его игнорировать, или спользовать не всю информацию — на -O0 оно скорее всего просто будет отбрасываться, к примеру, или если ты напишешь какую-то слишком замутную хуйню, компилятор скажет "нипанимаю, насяльника" и проигнорирует всё.

                        Хотя, если assert сделан исключительно средствами языка, и не является чем-то специальным для компилятора, то [[assume]] может заставить копелятор выкинуть код ассерта.
                        Ответить
                        • Бля, а ведь это не будет эквивалентом. [[assume]] может влиять на кодогенерацию до своего появления.

                          void foo(bar* baz)
                          {
                              if (baz != nullptr)
                                  baz.kukarek();
                              assert(baz != nullptr);
                              [[assume(baz != nullptr)]]
                          }

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

                          Поэтому при передаче нулевого указателя ассерт даже не сработает, потому что программу распидорасит при вызове метода по нулевому указателю.
                          Ответить
                      • Кстати, если контракты всё-таки засунут в С++, то [[assume(foo)]] будет эквивалентно [[expects axiom: foo]], тогда можно будет зафигачить вместо axiom: [[expects audit: foo]] или [[expects default: foo]], чтобы оно ещё и проверяло на валидность. Это поменяет поведение на вычисляющее аргументы, но скорее всего похуй.
                        Ответить
                • Между прочим, это "assume" уже было в "GNU C"
                  https://govnokod.ru/25997#comment510096
                  Ответить
                  • Оно есть во всех нормальных компиляторах, как раз с предложенным поведением*. Пропозал просто оборачивает все эти интрисики в аттрибут.

                    * Кроме ГЦЦ. ГЦЦ не умеет в невычисляемые выражения в данном случае. Но в 99% похуй.
                    Ответить
                    • Что значит "невычисляемые выражения"?
                      Ответить
                      • Это как у typeof:
                        int* x = NULL;
                        typeof(*x); // Не UB, выражение не вычисляется, соответственно разыменовывания нулевого указателя нет.
                        Ответить
                        • Каким образом это применимо к [[assume(какое-то-условие)]] и что именно GCC там не может ?
                          Например, можно сделать такую хуйню:
                          int* x = NULL;
                          if( !__builtin_types_compatible_p(typeof(*x), int) )  __builtin_unreachable()
                          Ответить
                          • Маткабоска, сколько сранья.
                            Разве в переменная-указатель может быть чем-то иным, кроме как целым числohm?
                            Ответить
                          • То, что не typeof единым.
                            Например: [[assume(++it != end)]] — мы обрабатываем не последний элемент. Значение it не должно поменяться.
                            У шланга __builtin_assume(++it != end) работает именно так. У ГЦЦ if(++it != end); else __builtin_unreachable(); инкрементирует it.
                            Ответить
                            • Я не знаю, почему ты так гонишь на меня, что я не понимаю твой язык. Это не из-за того, что ты не понимаешь русский. Ты гонишь, потому что с тобой никто не разговаривает. Тебе никто не нравится, ты сам себе не нравишься, и ты пишешь, что хочешь это изменить. Но ты ничего не изменишь, если не захочешь этого сам. И ты, как и большинство людей, не хочешь меняться. Поэтому ты и гонишь. Вот и всё.
                              Ответить
                            • А можно сказать
                              assume(it == 44) и выкинуть весь код проврки нахуй?)

                              Начинаются какие-то тонки игры между выражениями, вычисляемыми компилятором в момент копуляции, и рантайм хуйней
                              Ответить
                              • Подобное идёт уже очень давно.
                                К примеру
                                void foo(int i)
                                {
                                    char c[4];
                                    c[i] = 'a';
                                    //...
                                }

                                В этом коде компилятор уже считает, что i >= 0 и i < 4, потому что инче UB. Писать сюда [[assume(0 <= i && i < 4)]] бессмысленно — компилятор уже это предполагает и может делать любые трансформации с кодом. К примеру, он мог бы оперировать только над младшим байтом i, потому что в остальных всё равно должны быть нули.
                                Ответить
                                • Хочу, чтобы был ключ, вставляющий в дебажном явную проверку на i, и кидающий исключение

                                  Чтобы вместо УБ я видел более внятные ошибки пока их дебажу
                                  Ответить
                                  • std::array и MSVC. Он вставляет проверки на выход за границы контейнеров в дебаг-режиме.

                                    Или жди контрактов:
                                    void foo(int i)
                                        [[ expects: i >= 0 ]] 
                                        [[ expects: i < 4 ]]   
                                    {
                                    Ответить
        • Кстати, в расте тоже можно управлять аргументом self: будет он копироваться/муваться, или передаваться по ссылке (борроуться в терминах раста) и будет ли она константной.

          Структуры в Расте по умолчанию не копируются, а муваются (трейт копирования нужно заказывать явно) потому что раст вообще стсрается всё мувать в отличие от плюсов

          В купе с учением об оунершипе это может приводить к смешным баграм.
          Этот код (совершенно нормальный в С++ например) не скомпилируется в расте
          struct Rectangle {
              width: u8,
              height: u8,
          }
          
          
          impl Rectangle {
              fn square(self) -&gt; u8 {
                  self.width * self.height
              }
          }
          
          
          fn main() {
              let r = Rectangle { width: 10, height: 10 };
              let sq = r.square();
              let sq2 = r.square();
          }
          Ответить
    • Никола Тесла не только никогда не состоял в браке, но и в интимных отношениях.

      Он объяснял это болезнью, которую пережил ещё до своего 18-летия, что сделало его равнодушным к женскому полу. Но Тесла считал, что это даже к лучшему.

      «Я сэкономил очень много времени и очень много энергии для научных исследований. Наука — вот моя первая, главная и единственная любовь. Другой мне не надо», — писал он в 80 лет.
      Ответить
    • After selling as many as 700,000 copies, it was discovered that the software actually did nothing except write more swap data to disk with worse performance and report false memory savings, leading it to be called "placebo software".
      Ответить
      • Пошёл нахуй с моей ветки, гандон.
        Ответить
      • Кстати, можно ли сделать swap на NFS mount, чтобы опровергнуть фразу "you wouldn't download RAM"?
        Ответить
        • https://yewtu.be/watch?v=minxwFqinpw
          Ответить
        • )) Кстати, если без зеленого, то отвал сети приведет к кернел паник

          Я не знаю, нужна ли реализации NFSа виртуальная память (или там всё невыгружаемо и в ядре) но скорее всего нужна, так что такая мандала даже не запустится.

          Мне стало интересно, а бывают-ли такие додики IRL. Разумеется, любые додики бывают

          https://social.technet.microsoft.com/Forums/lync/en-US/7424027c-fb9b-4202-a177-2a11581309d0/moving-pagefilesys-to-an-iscsi-device

          (iscsi это такой SAN -- конкурент файберченнлов)
          Ответить

    Добавить комментарий