LINUX.ORG.RU

Языку программирования Rust исполнилось 10 лет

 , ,


1

5

15 мая этого года исполнилось 10 лет с момента выхода первой стабильной версии языка программирования Rust, разрабатываемого Mozilla совместно с сообществом.

Основные итоги за это время:

Попытки собрать истории растового успеха: раз, два.

>>> Официальный сайт

anonymous

Проверено: hobbit ()
Последнее исправление: hobbit (всего исправлений: 4)
Ответ на: комментарий от necromant

«class» фичу завезли только в 5.38 https://perldoc.perl.org/5.38.0/perldelta каких 20 лет?

Это сахар. Классы в perl5 всегда были, хоть и костыльные. В чем-то «bless» классы даже лучше, потому что заставляют задуматься, а стоит ли городить ООП. Обычно не стоит, но если сильно хочется, то давно есть Moose и другие объектные модели. В перле с метапрограммированием всё в порядке, и вообще мимокродилы перл сильно недооценивают, считая его за sed-переросток.

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

Этот код является иллюстрацией того, как выглядит «полноценный язык с нормальным ООП» по мнению отдельных комментаторов.

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

в некоей области памяти может содержаться только обьект того класса, каким эта область памяти типизирована. (кроме специального случая - union).

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

это может быть только если область типизирована как union {A, B} и туда присвоили B. и по другому - никак.

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

ну конволютность есть для мимпроходящих

ибо наследование struct иначе (а чё типо пустовать комбе) чем наследование obj(class) <- и даже это не вполне точное

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

а реализация ооп в плюсах это тот ещё компромисс

в сырце кроме умолчальности доступа к полям ведь и поведение сменится если g/struct/class/g(?!) :) ?

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

мимопроходящие могли бы ошибится и предположить что связывание в другой момент и следовательно 7 ибо наследование полиморфизм вот эта вот вся машинерия :)

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

утята любат свою маму-каркадилицу

порадуемся же за них и неё

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

Это просто код на цпп, написанный по стандарту, никаких уб или ещё чего. В функцию отправляется объект класса B, приходит объект класса A. «Полноценный язык с нормальным ООП».

а при чем здесь ООП? Вы передаёте в функцию по значению, оно и копируется из того источника что вы предоставили. Простое правило передачи по значению это азы языка.

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

До этого разве были «роли»? Их там дальше будут добавлять. Я так понял поэкспериментировали в Raku и решили себе взять уже готовое и протестированное, чуток подправив.

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

а при чем здесь ООП?

Ну не знаю, может при том, что идёт работа с объектами?

Простое правило передачи по значению это азы языка.

Не знаю, с чем вы пытаетесь спорить. Моя точка зрения заключается в том, что вот это вот нельзя называть нормальным ООП.

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

Это не мой код - это код по ссылке от unC0Rr, вопросы к нему.

Вы опубликовали, вам и отвечать.

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

а при чем здесь ООП?

Ну не знаю, может при том, что идёт работа с объектами?

Какая здесь работа с объектами еще раз? Вот код на С:

struct A {
    int a;
};

struct B {
    struct A parent;
    int b;
};

int a_value(struct A a) { return a.a;}

int main() {
    struct B b;  
    b.parent.a = 3;
    b.b = 4;

    return a_value(b.parent);
}

Компилируется в тот же код, что и С++:

a_value:
        mov     eax, edi
        ret
main:
        mov     eax, 3
        ret

Можете ответить почему? Где в языке С вы нашли объекты? То есть даже пример не удосужились нормальный предоставить, чтобы задействовать ООП из С++ и пытаетесь критиковать язык. Это глупо выглядит.

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

return a_value(b.parent);

Когда перепишешь в виде return a_value(b), тогда и говори, что код эквивалентный. Как там потроха объектов реально представлены - совершенно не важно, важна семантика операций. В цпп я передаю b, а не какое-то его поле.

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

Вот код на С:

int a_value(int a) {
    return a;
}

int main() {
    return 3;
}

Компилируется в тот же код:

a_value(int):
        mov     eax, edi
        ret
main:
        mov     eax, 3
        ret

Можете ответить почему? В примере даже структур нет, как же так, что не так с этим примером?

unC0Rr ★★★★★
()
Последнее исправление: unC0Rr (всего исправлений: 1)
Ответ на: комментарий от necromant
cat test.cpp
struct A {
    int a;
};

struct B {
    struct A parent;
    int b;
};

int a_value(struct A a) { return a.a;}

int main() {
    struct B b;
    b.parent.a = 3;
    b.b = 4;

    return a_value(b.parent);
}

gcc -S test.cpp
	.file	"test.cpp"
	.text
	.globl	_Z7a_value1A
	.type	_Z7a_value1A, @function
_Z7a_value1A:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	%edi, -4(%rbp)
	movl	-4(%rbp), %eax
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	_Z7a_value1A, .-_Z7a_value1A
	.globl	main
	.type	main, @function
main:
.LFB1:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movq	%fs:40, %rax
	movq	%rax, -8(%rbp)
	xorl	%eax, %eax
	movl	$3, -16(%rbp)
	movl	$4, -12(%rbp)
	movl	-16(%rbp), %eax
	movl	%eax, %edi
	call	_Z7a_value1A
	nop
	movq	-8(%rbp), %rdx
	subq	%fs:40, %rdx
	je	.L5
	call	__stack_chk_fail@PLT
.L5:
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE1:
	.size	main, .-main
	.ident	"GCC: (GNU) 15.1.1 20250425"
	.section	.note.GNU-stack,"",@progbits

clang++ -S  test.cpp 
	.text
	.file	"test.cpp"
	.globl	_Z7a_value1A                    # -- Begin function _Z7a_value1A
	.p2align	4, 0x90
	.type	_Z7a_value1A,@function
_Z7a_value1A:                           # @_Z7a_value1A
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register %rbp
	movl	%edi, -4(%rbp)
	movl	-4(%rbp), %eax
	popq	%rbp
	.cfi_def_cfa %rsp, 8
	retq
.Lfunc_end0:
	.size	_Z7a_value1A, .Lfunc_end0-_Z7a_value1A
	.cfi_endproc
                                        # -- End function
	.globl	main                            # -- Begin function main
	.p2align	4, 0x90
	.type	main,@function
main:                                   # @main
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register %rbp
	subq	$32, %rsp
	movq	%fs:40, %rax
	movq	%rax, -8(%rbp)
	movl	$0, -24(%rbp)
	movl	$3, -16(%rbp)
	movl	$4, -12(%rbp)
	movl	-16(%rbp), %eax
	movl	%eax, -20(%rbp)
	movl	-20(%rbp), %edi
	callq	_Z7a_value1A
	movl	%eax, -28(%rbp)                 # 4-byte Spill
	movq	%fs:40, %rax
	movq	-8(%rbp), %rcx
	cmpq	%rcx, %rax
	jne	.LBB1_2
# %bb.1:
	movl	-28(%rbp), %eax                 # 4-byte Reload
	addq	$32, %rsp
	popq	%rbp
	.cfi_def_cfa %rsp, 8
	retq
.LBB1_2:
	.cfi_def_cfa %rbp, 16
	callq	__stack_chk_fail@PLT
.Lfunc_end1:
	.size	main, .Lfunc_end1-main
	.cfi_endproc
                                        # -- End function
	.ident	"clang version 19.1.7"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym _Z7a_value1A
	.addrsig_sym __stack_chk_fail

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

«Как правило»,«зачастую» и т.д. не тождественно «всегда».

Я в курсе :) Просто привел реальный пример исключения из '«Как правило»,«зачастую»'

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

Это заморочка от джавистов, питонистов и им подобных. У них переменная структурного типа всегда есть ССЫЛКА на структурное значение.

А в с++ переменная структурного типа есть САМО структурное значение. Чтобы в с++ было как в жаве и прочих - надо добавлять к переменной ссылку

то есть чтобы записать жавское

SomeType x

в си++ надо писать

SomeType& x;

а джавовское

some_fun(SomeType p)

имеет с++ эквивалент

some_fun(SomeType& p)

в обоих случаях в функцию будет передаваться адрес обьекта.

а если на с++ написать

some_fun(SomeType p)

то будет передаваться в параметр не адрес, а копироваться сам обьект, даже если он размером 100 мб. потому так на с++ никто не пишет.

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

Устаревшее это кобол. А C++ это язык в самом расцвете сил. Новые стандарты выходят. Куча конкурирующих компиляторов. Куча хороших IDE. Куча новых проектов. Изучают в учебных заведениях. Много вакансий и много соискателей. Нет никаких оснований считать его устаревшим.

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

я вам даже ассемблерный листинг привел, тот же самый. Это вот к такому коду и приводит ваш код на C++. А всё идет от незнания, что вы задекларировали в функции:

int a_value(A a) { return a.value();}

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

Это вот тоже самое, что создать long int значение и впихивать его в int, к примеру. И потом ругаться на язык и его ООП.

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

Гугл уже пилит свою замену Плюсам. Есть Раст ещё.

Мало ли что там «гугл пилит». Они уже столько всего «напилили» и закопали, что есть аж целое «кладбище проектов гугл».

https://killedbygoogle.com/

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

компилятор не может ошибаться!

Если в вашей программе не обнаружено ошибок - позовите автора компилятора - он исправит в нем ошибки ! :)

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

дык намёк на неконсистентность синтаксиса плюсоси

так то в стандарте всё чётно определено - и вопрос не в том почему отправляя б наследника а отрабатывает на value структурах метод формального параметра а не динамический резолв

ибо ТАК ОПРЕДЕЛЕННО - собственно такая вырвиглазность и делеает плюсистов дорогими

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

хохма ещё более лучше одевательная

изначально всё было по значению и именно в сырце вполне с-поведение

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

крч когнитивный дисонанс 3 а не семёрка ( туз уходит в зрительский зал) именно в том что происходит обратный эффект слова оверайд наследование и прочие оопие

зы - хохма именно в том что семантику прикручивают к лакунам и как итог Датчанин реально Глыба что этого Слона слепых мудрецов всё ещё во вменяемом для любителей поглощать кактусы(но в ограниченых количествах) могёт

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

так то в стандарте всё чётно определено - и вопрос не в том почему отправляя б наследника а отрабатывает на value структурах метод формального параметра а не динамический резолв

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

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

а поскольку тут написано просто «значение класса A», то есть «область памяти типизированная как класс A», то резолва не надо. У этой области памяти VMT указатель будет указывать на таблицу методов класса A, даже если туда присваивали обьект класса В.

Потому тут даже нечего резолвить. там в рантайме, в VMT всегда будет реализация виртуального метода от класса A.

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

дык именно

пишем манчестер читаем бирмингем

а потом такие читали не могут в старо английский

хохма именно в валию-типах которые не полироморфятся ибо всё известно уже на этапе компиляции в отличии от vtable

что не отменяет факта что код вводит «неучей» в заблуждение очередные «ложные друзья переводчика»

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

а в полу(и умных и крассивых) жабе и шарпе общеобрыганские боксинг анбоксинг для валию<->через_

не ну на придумавать обьяснения в стандарте всё запостулированно

тока результат такового трэйдоффа привнесённая сложность

по факту современные что плюсы что ещё какой зверь синтаксически сложнее пристнопамятного алгола68 - однкако без элегантности хорошо фундированной математики

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

В функцию отправляется объект класса B, приходит объект класса A

Ничто никуда не отправляется и не приходит – при передаче параметра по значению вызывается A(const A& ) { … }, в данном случае созданный компилятором, с фактическим параметром типа const B&, который компилятор вполне законно кастит к const A&. Естественно, конструктор копии A ничего не знает про B, и копирует только поля A. Мозг автора вопроса поражен ссылочными типами в java или C#.

rmammoth
()
Последнее исправление: rmammoth (всего исправлений: 2)
Ответ на: комментарий от rmammoth

автора вопроса

Все так яростно защищают цпп, что видят вопрос там, где его нет.

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

ассемблерный листинг

Ассемблерный листинг не имеет никакого отношения к семантике языка. Можно много на чём написать код, приводящий к такому же асму. От этого какой-нибудь хаскель не становится сями со всратой эмуляцией классов на структурах.

создать long int значение и впихивать его в int, к примеру. И потом ругаться на язык

Отличный пример, кстати. Логика такого впихивания настолько же тупая, как у приведения B к A. Без специального запроса от программиста, в котором он клянётся, что так и задумывал, производиться не должно.

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

Можно и сейчас поговорить. Можно было и до того как Гугл что-то начинал. Запрета нет.

только к чему вы это написали?

Очевидно к чему.

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

Не факт, что эти проекты что-то стоили. Умерли и умерли. Переживать не о чем. Может они изначально были мёртвыми.

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

Логика такого впихивания настолько же тупая, как у приведения B к A.

Ну вот у вас обьекты - кошка(класс Cats) и собака(class Dogs). Их нельзя присвоить в переменную типа Animal?

что мешает? кошка и собака - не животные?

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

кошка и собака - не животные?

Допустим, что животные. Почему вдруг можно запихивать кошку в пробирку с животными? Какой смысл вообще в отрезании всего, что делает кошку кошкой и оставлении только того, что делает её животным?

Замечу, я не говорю об интерфейсе, когда мы можем сказать, да этот объект (кошка, но мы точно не знаем) животное, она имеет свойства животного. При слайсинге мы натурально отсекаем всякую возможность кошке быть чем-то большим, чем кучкой биологического материала.

class Animal {
public:
    virtual void speak() { std::cout << "???\n"; }
};

class Cat : public Animal {
public:
    void speak() override { std::cout << "Meow!\n"; }
};

int main() {
    Cat c;
    Animal a = c;

    a.speak();
}
unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

Если тебя очень напрягает, можно так:

class A {
  public:
    A() = default;
    template<typename T> A(const T &) requires (!std::is_same_v<A, T>) = delete;
    template<typename T> A &operator=(const T &) requires (!std::is_same_v<A, T>) = delete;
};

class B: public A {
};

void foo(A) {
}

int main() {
    A a;
    B b;
    a = b; // Ошибка компиляции
    foo(b); // Ошибка компиляции
    return 0;
}
rmammoth
()
Последнее исправление: rmammoth (всего исправлений: 4)
Ответ на: комментарий от unC0Rr

Не, я не предлагаю фиксить цпп, лишь не называть его «полноценным языком с нормальным ооп».

Вроде никто не собирается скрывать, что в C++ полиморфизм реализуется через ссылки и указатели, что не так? Кстати, ровно так же это работает в Java или C#, только там невозможно передать объект ссылочного типа по значению – он всегда ссылка, по сути, неявный указатель.

rmammoth
()
Ответ на: комментарий от unC0Rr
Аnimal a;
Animal b = a;

это создает Animal копию b обьекта a. Тут же все чисто, присваивать значения можно, они одного типа.

а это создает копию Animal свойств обьекта типа Cat.

Cat a;
Animal b = a;

в обоих случаях присваивались свойства класса Animal, просто во втором случае у обьекта типа Cat были доп. свойства которые нам не нужны в данном рассмотрении. потому они не копировались.

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

Не, я не предлагаю фиксить цпп, лишь не называть его «полноценным языком с нормальным ооп».

Так с «нормальным» ООП и нет почти языков то - по пальцам руки фрезеровщика можно только перечислить такие, где есть посылка сообщений… Я вот кроме Smalltalk, Objective-C и не припомню остальных. В каком-то виде Erlang более ООП чем остальные.

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

Никогда не был в секте почитателей Торвальдса. Более того даже не считал его супер умным или талантиливым. Просто он успел попасть в удачно в нишу и встать под GPL - все его заслуги.

Когда он высказался про Си++, показывал *аки Нвидии, обобщал справедливый хейт в сторону Кремля и его деяний в сторону всей русской нации в целом - лишь убедили меня что моё первичное впечатление о Торвальдсе было правдой, только с нейтрально-скептического отношения к нему вытиснилось в область неуважения к этому человеку, и даже отношения к не то что как «он не супер умный», а к оценке его как человека в общем глуповатого, но хорошо выдресеровавшего в себе навыки достаточные для того чем он сейчас занимается.

P.S. для своих личных (ну типа пет-проектов) проекты в т.ч. новые выбираю Си++, иногда смотрю в сторону Джавы или Шарпа (в Шарпе мне понравился MAUI - когда один проект, один код, но приложение сразу компилируется под Windows, Android и IOS).

В общем пока к Расту я отношусь пренебрежительно, спасибо за это его фанатам, ну и конечно тому что мне, сложилось так, реально по кайфу Си++, ООП, особенно нравятся код с шаблонной магией, sfinae и вычислениями во время компиляции, поэтому конечно (вероятно тоже будучи не особо умным) я начинаю хейтить Раст, но совершенно не исключаю вероятности того что я однажды попробую и мне понравится, но пока вижу так что я раньше умру чем дойдут руки пробовать Раст, т.к. Плюсы более чем устраивают и нравятся, а времени под всё не хватает. К слову я когда-то хейтил Плюсы и любил только Си, а сейчас наоборот - Плюсы любимый язык, а далее Джава, Шарп и Си - вот какой-то такой список моих любимых ЯП в порядке убывания любви, но все же любви. А самые ненавидимые это Питон и Раст. При том что Раст я не трогал, а только смотрел примеры кода на нём (так что это не супер объективно), а вот Питон я трогал и писал на нём около года - «пипец тошнотворно», такое впечатление, и рад что ныне забыл этот Питон что без интернета даже Привет мир не напишу на нём :)

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

Гы забавно, есть еще Лисп, и я когда учился в шараге, там надо было в курсе «парадигмы программирования» писать на Лиспе - вот Лисп это рилли самое худшее что я видел, но т.к. о нём почти не говорят, не продвигают, то я знаю что он просто есть и никаких эмоций не вызывает, в отличии от Раста или Питона, хотя такие при всём хейте к Расту и Питону и безэмоциональному глухому хейту к Лиспу - если предложат безальтернативный выбор на чем ты будешь писать на Лиспе или Расте или Питоне - то конечно не на Лиспе :)

И знаете что, я наверное выбрал бы Раст, т.к. от Питона я точно знаю что меня тошнит, а Раст имеет хотя бы вероятность на иной исход :)

bonta ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.