LINUX.ORG.RU

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

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

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

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

Ну, что-нибудь типа такого:

fn new<F>(f: F) where F: Fn() + Clone + 'static

К сожалению, у меня сейчас нет времени расписывать.

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

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

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

Да, это подходит, спасибо. Только писанины много не очевидной, как минимум для новичка. Тут ещё вариант придумал. Что скажете, есть у него минусы по сравнению с вашим решением?

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

Что скажете, есть у него минусы по сравнению с вашим решением?

  1. Не собирается rustc, который в Debian 10(https://packages.debian.org/stable/rust/rustc):
rustc -C opt-level=3 2.rs
error[E0277]: expected a `std::ops::Fn<()>` closure, found `std::boxed::Box<[closure@2.rs:12:24: 12:43]>`
  --> 2.rs:16:17
   |
16 |         bx_cl = Box::new(cl1.clone());
   |                 ^^^^^^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `std::boxed::Box<[closure@2.rs:12:24: 12:43]>`
   |
   = help: the trait `std::ops::Fn<()>` is not implemented for `std::boxed::Box<[closure@2.rs:12:24: 12:43]>`
   = note: wrap the `std::boxed::Box<[closure@2.rs:12:24: 12:43]>` in a closure with no arguments: `|| { /* code */ }
   = note: required for the cast to the object type `dyn std::ops::Fn()`

error[E0277]: expected a `std::ops::Fn<()>` closure, found `std::boxed::Box<[closure@2.rs:13:24: 13:44]>`
  --> 2.rs:18:17
   |
18 |         bx_cl = Box::new(cl2.clone());
   |                 ^^^^^^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `std::boxed::Box<[closure@2.rs:13:24: 13:44]>`
   |
   = help: the trait `std::ops::Fn<()>` is not implemented for `std::boxed::Box<[closure@2.rs:13:24: 13:44]>`
   = note: wrap the `std::boxed::Box<[closure@2.rs:13:24: 13:44]>` in a closure with no arguments: `|| { /* code */ }
   = note: required for the cast to the object type `dyn std::ops::Fn()`

error[E0277]: expected a `std::ops::Fn<()>` closure, found `std::boxed::Box<[closure@2.rs:20:24: 20:37 cl1:_]>`
  --> 2.rs:24:18
   |
24 |         bx_cl2 = Box::new(cl3);
   |                  ^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `std::boxed::Box<[closure@2.rs:20:24: 20:37 cl1:_]>`
   |
   = help: the trait `std::ops::Fn<()>` is not implemented for `std::boxed::Box<[closure@2.rs:20:24: 20:37 cl1:_]>`
   = note: wrap the `std::boxed::Box<[closure@2.rs:20:24: 20:37 cl1:_]>` in a closure with no arguments: `|| { /* code */ }
   = note: required for the cast to the object type `dyn std::ops::Fn()`

error[E0277]: expected a `std::ops::Fn<()>` closure, found `std::boxed::Box<[closure@2.rs:21:24: 21:37 cl2:_]>`
  --> 2.rs:26:18
   |
26 |         bx_cl2 = Box::new(cl4);
   |                  ^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `std::boxed::Box<[closure@2.rs:21:24: 21:37 cl2:_]>`
   |
   = help: the trait `std::ops::Fn<()>` is not implemented for `std::boxed::Box<[closure@2.rs:21:24: 21:37 cl2:_]>`
   = note: wrap the `std::boxed::Box<[closure@2.rs:21:24: 21:37 cl2:_]>` in a closure with no arguments: `|| { /* code */ }
   = note: required for the cast to the object type `dyn std::ops::Fn()`

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0277`.
fsb4000@orangepilite2:~/rust$ rustc -V
rustc 1.34.2

  1. Вообще я хотел посмотреть в Valgrind число аллокаций, мне кажется у вашего варианта их будет чуть больше, даже не смотря на оптимизирующий компилятор, но rustc из Debian не захотел собирать…

А так вроде больше минусов нет…

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

Поставил кое-где *, теперь компилируется под rustc 1.34.2

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=923a441a3f8675fce6431957bcfe6d72

Теперь запустил Valgrind:

  1. Мой вариант:
valgrind ./1
==2051== Memcheck, a memory error detector
==2051== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2051== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==2051== Command: ./1
==2051== 
true
==2051== 
==2051== HEAP SUMMARY:
==2051==     in use at exit: 0 bytes in 0 blocks
==2051==   total heap usage: 20 allocs, 20 frees, 3,441 bytes allocated
==2051== 
==2051== All heap blocks were freed -- no leaks are possible
==2051== 
==2051== For counts of detected and suppressed errors, rerun with: -v
==2051== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
  1. Ваш вариант, исправленный для компиляции rustc 1.34.2:
valgrind ./2
==2052== Memcheck, a memory error detector
==2052== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2052== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==2052== Command: ./2
==2052== 
true
==2052== 
==2052== HEAP SUMMARY:
==2052==     in use at exit: 0 bytes in 0 blocks
==2052==   total heap usage: 22 allocs, 22 frees, 3,449 bytes allocated
==2052== 
==2052== All heap blocks were freed -- no leaks are possible
==2052== 
==2052== For counts of detected and suppressed errors, rerun with: -v
==2052== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Собирал так:

rustc -C opt-level=3 2.rs
rustc -C opt-level=3 1.rs
fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от fsb4000

Вот что у меня получилось:

Ваш - total heap usage: 20 allocs, 20 frees, 3,361 bytes allocated

Мой - total heap usage: 22 allocs, 22 frees, 3,369 bytes allocated

andalevor ★★
() автор топика

Мой вариант делал не то что надо. Так что пока единственный верный вариант тут.

andalevor ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.