ФлеймФорумПрограммирование

Стоит ли изучать новый язык Rust? (8 стр)

Страницы: 17 8 9 10291 Следующая »
#105
17:48, 6 мар 2018

FlyOfFly
> Тогда он и на си не будем понимать.
Не обязательно, три строчки понять проще сотни.

Тем более, он может подсмотреть у Кнута:

P<=AVAIL, LLINK(P)<-X, RLINK(P)<-RLINK(X), LLINK(RLINK(X))<-P, RLINK(X)<-P

Кстати, перевести это в коды Кнут постеснялся ввиду очевидности.

#106
17:51, 6 мар 2018

gudleifr
> Для замены одной очевиднейшей строки кода.
Ты про неё?

#define BLIST(X) p##X next, pred;

Объясни пожалуйста, что она делает такого невероятного, что уделывает по функциональности весь этот код на Rust?

И зачем тут так много написано кода  для реализации списков?
https://github.com/troydhanson/uthash/blob/master/src/utlist.h
Мне кажется он просто лох какой-то, который не умеет на C писать всё одной строкой.

#107
17:53, 6 мар 2018

gudleifr
> P<=AVAIL, LLINK(P)<-X, RLINK(P)<-RLINK(X), LLINK(RLINK(X))<-P, RLINK(X)<-P

P<=AVAIL;
LLINK(P)<-X;
RLINK(P)<-RLINK(X);
LLINK(RLINK(X))<-P;
RLINK(X)<-P;
#108
17:58, 6 мар 2018

desss
> Ты про неё?
Вот видите, Вы уже путаете код вставки элемента с описателем элементов списка...

desss
> Объясни пожалуйста, что она делает такого невероятного, что уделывает по
> функциональности весь этот код на Rust?
Она делает ровно столько, сколько нужно для удобной работы с двусвязным списком на C.

#109
(Правка: 16 дек 2023, 18:58) 18:00, 6 мар 2018

desss
> P<=AVAIL;
> LLINK(P)<-X;
> RLINK(P)<-RLINK(X);
> LLINK(RLINK(X))<-P;
> RLINK(X)<-P;

Извините,
я
все
забываю,
что
имею
дело
с
"современным
программистом".

#110
18:05, 6 мар 2018

gudleifr
> Вот видите, Вы уже путаете код вставки элемента с описателем элементов списка...
Хаха.
gudleifr
> Извините,
> я
> все
> забываю,
> что
> инею
> дело
> с
> "современным
> программистом".
Ну что ты, я тоже умею писать в одну строчку:

// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT// file at the top-level directory of this distribution and at// http://rust-lang.org/COPYRIGHT.//// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your// option. This file may not be copied, modified, or distributed// except according to those terms.//! A doubly-linked list with owned nodes.//!//! The `LinkedList` allows pushing and popping elements at either end//! in constant time.//!//! Almost always it is better to use `Vec` or [`VecDeque`] instead of//! [`LinkedList`]. In general, array-based containers are faster,//! more memory efficient and make better use of CPU cache.//!//! [`LinkedList`]: ../linked_list/struct.LinkedList.html//! [`VecDeque`]: ../vec_deque/struct.VecDeque.html#![stable(feature = "rust1", since = "1.0.0")]use core::cmp::Ordering;use core::fmt;use core::hash::{Hasher, Hash};use core::iter::{FromIterator, FusedIterator};use core::marker::PhantomData;use core::mem;use core::ops::{BoxPlace, InPlace, Place, Placer};use core::ptr::{self, NonNull};use boxed::{Box, IntermediateBox};use super::SpecExtend;/// A doubly-linked list with owned nodes.////// The `LinkedList` allows pushing and popping elements at either end/// in constant time.////// Almost always it is better to use `Vec` or `VecDeque` instead of/// `LinkedList`. In general, array-based containers are faster,/// more memory efficient and make better use of CPU cache.#[stable(feature = "rust1", since = "1.0.0")]pub struct LinkedList<T> { head: Option<NonNull<Node<T>>>, tail: Option<NonNull<Node<T>>>, len: usize, marker: PhantomData<Box<Node<T>>>,}struct Node<T> { next: Option<NonNull<Node<T>>>, prev: Option<NonNull<Node<T>>>, element: T,}/// An iterator over the elements of a `LinkedList`.////// This `struct` is created by the [`iter`] method on [`LinkedList`]. See its/// documentation for more.////// [`iter`]: struct.LinkedList.html#method.iter/// [`LinkedList`]: struct.LinkedList.html#[stable(feature = "rust1", since = "1.0.0")]pub struct Iter<'a, T: 'a> { head: Option<NonNull<Node<T>>>, tail: Option<NonNull<Node<T>>>, len: usize, marker: PhantomData<&'a Node<T>>,}#[stable(feature = "collection_debug", since = "1.17.0")]impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Iter") .field(&self.len) .finish() }}// FIXME(#26925) Remove in favor of `#[derive(Clone)]`#[stable(feature = "rust1", since = "1.0.0")]impl<'a, T> Clone for Iter<'a, T> { fn clone(&self) -> Self { Iter { ..*self } }}/// A mutable iterator over the elements of a `LinkedList`.////// This `struct` is created by the [`iter_mut`] method on [`LinkedList`]. See its/// documentation for more.////// [`iter_mut`]: struct.LinkedList.html#method.iter_mut/// [`LinkedList`]: struct.LinkedList.html#[stable(feature = "rust1", since = "1.0.0")]pub struct IterMut<'a, T: 'a> { list: &'a mut LinkedList<T>, head: Option<NonNull<Node<T>>>, tail: Option<NonNull<Node<T>>>, len: usize,}#[stable(feature = "collection_debug", since = "1.17.0")]impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("IterMut") .field(&self.list) .field(&self.len) .finish() }}/// An owning iterator over the elements of a `LinkedList`.////// This `struct` is created by the [`into_iter`] method on [`LinkedList`][`LinkedList`]/// (provided by the `IntoIterator` trait). See its documentation for more.////// [`into_iter`]: struct.LinkedList.html#method.into_iter/// [`LinkedList`]: struct.LinkedList.html#[derive(Clone)]#[stable(feature = "rust1", since = "1.0.0")]pub struct IntoIter<T> { list: LinkedList<T>,}#[stable(feature = "collection_debug", since = "1.17.0")]impl<T: fmt::Debug> fmt::Debug for IntoIter<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("IntoIter") .field(&self.list) .finish() }}impl<T> Node<T> { fn new(element: T) -> Self { Node { next: None, prev: None, element, } } fn into_element(self: Box<Self>) -> T { self.element }}// private methodsimpl<T> LinkedList<T> { /// Adds the given node to the front of the list. #[inline] fn push_front_node(&mut self, mut node: Box<Node<T>>) { unsafe { node.next = self.head; node.prev = None; let node = Some(Box::into_raw_non_null(node)); match self.head { None => self.tail = node, Some(mut head) => head.as_mut().prev = node, } self.head = node; self.len += 1; } } /// Removes and returns the node at the front of the list. #[inline] fn pop_front_node(&mut self) -> Option<Box<Node<T>>> { self.head.map(|node| unsafe { let node = Box::from_raw(node.as_ptr()); self.head = node.next; match self.head { None => self.tail = None, Some(mut head) => head.as_mut().prev = None, } self.len -= 1; node }) } /// Adds the given node to the back of the list. #[inline] fn push_back_node(&mut self, mut node: Box<Node<T>>) { unsafe { node.next = None; node.prev = self.tail; let node = Some(Box::into_raw_non_null(node)); match self.tail { None => self.head = node, Some(mut tail) => tail.as_mut().next = node, } self.tail = node; self.len += 1; } } /// Removes and returns the node at the back of the list. #[inline] fn pop_back_node(&mut self) -> Option<Box<Node<T>>> { self.tail.map(|node| unsafe { let node = Box::from_raw(node.as_ptr()); self.tail = node.prev; match self.tail { None => self.head = None, Some(mut tail) => tail.as_mut().next = None, } self.len -= 1; node }) } /// Unlinks the specified node from the current list. /// /// Warning: this will not check that the provided node belongs to the current list. #[inline] unsafe fn unlink_node(&mut self, mut node: NonNull<Node<T>>) { let node = node.as_mut(); match node.prev { Some(mut prev) => prev.as_mut().next = node.next.clone(), // this node is the head node None => self.head = node.next.clone(), }; match node.next { Some(mut next) => next.as_mut().prev = node.prev.clone(), // this node is the tail node None => self.tail = node.prev.clone(), }; self.len -= 1; }}#[stable(feature = "rust1", since = "1.0.0")]impl<T> Default for LinkedList<T> { /// Creates an empty `LinkedList<T>`. #[inline] fn default() -> Self { Self::new() }}impl<T> LinkedList<T> { /// Creates an empty `LinkedList`. /// /// # Examples /// /// ``` /// use std::collections::LinkedList; /// /// let list: LinkedList<u32> = LinkedList::new(); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> Self { LinkedList { head: None, tail: None, len: 0, marker: PhantomData, } } /// Moves all elements from `other` to the end of the list. /// /// This reuses all the nodes from `other` and moves them into `self`. After /// this operation, `other` becomes empty. /// /// This operation should compute in O(1) time and O(1) memory. /// /// # Examples /// /// ``` /// use std::collections::LinkedList; /// /// let mut list1 = LinkedList::new(); /// list1.push_back('a'); /// /// let mut list2 = LinkedList::new(); /// list2.push_back('b'); /// list2.push_back('c'); /// /// list1.append(&mut list2); /// /// let mut iter = list1.iter(); /// assert_eq!(iter.next(), Some(&'a')); /// assert_eq!(iter.next(), Some(&'b')); /// assert_eq!(iter.next(), Some(&'c')); /// assert!(iter.next().is_none()); /// /// assert!(list2.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn append(&mut self, other: &mut Self) { match self.tail { None => mem::swap(self, other), Some(mut tail) => { if let Some(mut other_head) = other.head.take() { unsafe { tail.as_mut().next = Some(other_head); other_head.as_mut().prev = Some(tail); } self.tail = other.tail.take(); self.len += mem::replace(&mut other.len, 0); } } } } /// Provides a forward iterator. /// /// # Examples /// /// ``` /// use std::collections::LinkedList; /// /// let mut list: LinkedList<u32> = LinkedList::new(); /// /// list.push_back(0); /// list.push_back(1); /// list.push_back(2); /// /// let mut iter = list.iter(); /// assert_eq!(iter.next(), Some(&0)); /// assert_eq!(iter.next(), Some(&1)); /// assert_eq!(iter.next(), Some(&2)); /// assert_eq!(iter.next(), None); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter<T> { Iter { head: self.head, tail: self.tail, len: self.len, marker: PhantomData, } } /// Provides a forward iterator with mutable references. /// /// # Examples /// /// ``` /// use std::collections::LinkedList; /// /// let mut list: LinkedList<u32> = LinkedList::new(); /// /// list.push_back(0); /// list.push_back(1); /// list.push_back(2);
#111
18:10, 6 мар 2018

desss
> Ну что ты, я тоже умею писать в одну строчку:
Очевидно, не умеете. И с "двумя косыми" лажанули, и пробелы лишние, и текст оказался шире окна.

#112
18:13, 6 мар 2018

gudleifr
> Т.е. для того, чтобы заменить три очевидные строчки кода сотней понадобился
> отдельный "разработчик"? Браво крестам!
Этот разработчик может быть всего одним на всю планету. В сумме трудозатраты уменьшатся, по сравнению с сишной макроснёй. Качество программных продуктов также возрастёт.

#113
18:15, 6 мар 2018

gudleifr
> текст оказался шире окна.
Уверяю вас, что это абсолютно нормально когда умеешь помещать всю программу в одну строку :)
А если вам тяжеловато читать подобное, то это ваши проблемы. Нужно было лучше учиться писать программы в одну строку.

> Для замены одной очевиднейшей строки кода.
Вы между прочим так и не привели, эту самую строку кода.
Может это всё же она?

#define BLIST(X) p##X next, pred;

Потому что две другие строки, относятся к односвязному списку, а не к двусвязному.

Между прочим странно, что реализация односвязного списка на C занимает в два раза больше строк кода чем двусвязного.
Не находите?

#114
18:23, 6 мар 2018

Panzerschrek[CN]
> Этот разработчик может быть всего одним на всю планету.
Не-а. Откройте книжку Ахо и компании и посмотрите, как структуры данных оптимизируются под задачу. Кубический универсальный двусвязный список в вакууме на все случаи жизни - это только для быдла.

Panzerschrek[CN]
> В сумме трудозатраты уменьшатся, по сравнению с сишной макроснёй.
Хрена. Посмотрите на ОО-код. Он нихрена не короче обычного C-шного, невзирая на на все шаблоны и библиотеки.

Panzerschrek[CN]
> Качество программных продуктов также возрастёт.
Это где же Вы в наше время видели качественный код? Во сне? Сколько раз в неделю Сбербанк падает? Куда Тесла полетела?

desss
> Вы между прочим так и не привели, эту самую строку кода.

gudleifr
>... у Кнута:
>
> P<=AVAIL, LLINK(P)<-X, RLINK(P)<-RLINK(X), LLINK(RLINK(X))<-P, RLINK(X)<-P
>
> Кстати, перевести это в коды Кнут постеснялся ввиду очевидности.

Найдете, где Вы лажанули в  push_back()?

desss
> Между прочим странно, что реализация односвязного списка на C занимает в два
> раза больше строк кода чем двусвязного.
Т.е. Вы совсем не понимаете, что там написано?

#115
18:31, 6 мар 2018

gudleifr
> Т.е. Вы совсем не понимаете, что там написано?
Я просто очень доверяю вашему авторитету.
Вы сказали:

gudleifr
> И все ради того, чтобы заменить тупое C-шное
>
> /* Список типа X обязан иметь указатель X *next и деструктор del##X() */
> #define LIST(X) p##X next;
> #define FREE(X) free##X(p) p##X p; { if (p) { free##X(p->next); del##X(p);
> free(p); } }
> /* Двусвязный список типа X обязан иметь указатели X *next, *pred и деструктор
> del##X() */
> #define BLIST(X) p##X next, pred;

Из этого следует, что весь код по ссылке https://github.com/rust-lang/rust/blob/0ff9872b2280009f094af0df3d… inked_list.rs
написан для того чтобы заменить приведенный вами код.
По ссылке я вижу полную реализацию двусвязного списка и широчайшего API для манипуляции с ним.
Значит приведенный вами код делает ровно то же самое.

И похоже даже больше - не могу разобрать, но кажется он включает в себя реализацию еще и односвязного списка.

> P<=AVAIL, LLINK(P)<-X, RLINK(P)<-RLINK(X), LLINK(RLINK(X))<-P, RLINK(X)<-P
А это не код . Это псевдокод. И в книге он занимает две строки: https://i.imgur.com/WUhQCgw.png

#116
18:40, 6 мар 2018

desss
> Значит приведенный вами код делает ровно то же самое.
Да разумеется, т.к. написать

P<=AVAIL, LLINK(P)<-X, RLINK(P)<-RLINK(X), LLINK(RLINK(X))<-P, RLINK(X)<-P

проще, чем

list.push_back(foo);

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

#117
18:43, 6 мар 2018

gudleifr
> Да разумеется, т.к. написать
>
> P<=AVAIL, LLINK(P)<-X, RLINK(P)<-RLINK(X), LLINK(RLINK(X))<-P, RLINK(X)<-P
>
> проще,

Ну это неправда. И что самое хреновое, это и писать сложнее, и читать.

#118
18:47, 6 мар 2018

1 frag / 2 deaths
> Ну это неправда.
Правда, правда... Просто, Вы привыкли к копипасте плохих учебников.

#119
18:51, 6 мар 2018

gudleifr
> Да разумеется, т.к. мне написать
> P<=AVAIL, LLINK(P)<-X, RLINK(P)<-RLINK(X), LLINK(RLINK(X))<-P, RLINK(X)<-P
>
> проще, чем
>
> list.push_back(foo);
исправлено.

Страницы: 17 8 9 10291 Следующая »
ФлеймФорумПрограммирование