Can I declare functions and define it later in Rust, like C++? - function

this example grabbed from geeksforgeeks.
// C++ program to demonstrate function
// declaration outside class
#include <bits/stdc++.h>
using namespace std;
class Geeks
{
public:
string geekname;
int id;
// printname is not defined inside class definition
void printname();
// printid is defined inside class definition
void printid()
{
cout << "Geek id is: " << id;
}
};
// Definition of printname using scope resolution operator ::
void Geeks::printname()
{
cout << "Geekname is: " << geekname;
}
int main() {
Geeks obj1;
obj1.geekname = "xyz";
obj1.id=15;
// call printname()
obj1.printname();
cout << endl;
// call printid()
obj1.printid();
return 0;
}
I mean, function like printname in this example.
And in rust..., this example grabbed from exercism and I modified little bit.
// This stub file contains items which aren't used yet; feel free to remove this module attribute
// to enable stricter warnings.
#![allow(unused)]
pub struct User {
name: String,
age: u32,
weight: f32,
}
impl User {
pub fn new(name: String, age: u32, weight: f32) -> Self;
pub fn name(&self) -> &str;
...
...
}
pub fn User::name(&self) -> &str {
unimplemented!()
}
...
...
like this or somewhat difference, but declare first definition later.
Sorry for my bad english, and therefore I included many lines of code and I needed to add some more detail because SO wants that.
There's no way to do this in Rust?

You can do the same thing in Rust. You can implement particular struct methods, from anywhere inside the crate.
This is mostly pointless in Rust, but I'm going to provide an example where this might prove useful.
Soundness concerns leak to the surrounding module, and thus you can reduce the scope of this issue by doing this:
mod a {
pub struct A;
impl A {
pub fn a(&self) {
// here we can't access any unsafe functions specific to A
// unsafe { some_unsafe_helper() }; // compiler error
println!("Called ::crate::a::A::a implemented in ::crate::a");
}
}
mod less_safe {
unsafe fn some_unsafe_helper() {}
impl super::A {
pub fn b(&self) {
// here we have to uphold invariants, in this case, by doing nothing
unsafe { some_unsafe_helper() };
println!("Called ::crate::a::A::b implemented in ::crate::a::less_safe");
}
}
}
}
fn main() {
let example = a::A;
example.a();
example.b();
}
This prints:
Called ::crate::a::A::a implemented in ::crate::a
Called ::crate::a::A::b implemented in ::crate::a::less_safe
Playground

Related

How do I write a function that returns itself?

What I want to make is a function, that returns itself, so I can call it like this:
foo()()...()
In C# it would be done via delegates:
delegate SelfFunc SelfFunc();
static void Main() {
SelfFunc foo = null;
foo = () => {
return foo;
};
foo()()...();
}
Anticipating questions like "why implement such silly behavior?": I want to sum numbers in a very strange way using single function continues calls: foo(1)(2)(3)() = 6, but in this question I just want to know how to return function itself. Example realization of this method that I made in C#. This is all just for fun and to learn Rust:
static int sum = 0;
delegate dynamic InfFunc(int i = int.MaxValue);
static void InfFuncTest() {
InfFunc f = null;
f = (int i) => {
if(i == int.MaxValue) {
return sum;
}
sum += i;
return f;
};
var g = f;
var value = g(1)(2)(3)();
Console.WriteLine(value);
}
A function that returns itself is possible on nightly.
First you need to enable the features unboxed_closures and fn_traits.
Then you can define a struct which, when called, returns self. The full code looks something like this:
#![feature(unboxed_closures, fn_traits)]
struct SelfFunc;
impl FnOnce<()> for SelfFunc {
type Output = SelfFunc;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self
}
}
Then you can call the function as many times as you want:
fn main() {
let f = SelfFunc;
f()()()()()();
}
Based on #cameron1024's answer, you can "overload" using traits, but you will need 2 structs to handle the empty case properly of foo() (here called Add) without any arguments returning 0.
#![feature(unboxed_closures, fn_traits)]
struct Add;
impl FnOnce<(u32,)> for Add {
type Output = AddImpl;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
AddImpl(args.0)
}
}
impl FnOnce<()> for Add {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
0
}
}
struct AddImpl(u32);
impl FnOnce<()> for AddImpl {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.0
}
}
impl FnOnce<(u32,)> for AddImpl {
type Output = AddImpl;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
Self(self.0 + args.0)
}
}
fn main() {
dbg!( Add(1)(2)(3)() );
dbg!( Add() );
}
Playground
If you do not care about the no-args foo() requirement, you can make Add a tuple struct instead and remove AddImpl:
#![feature(unboxed_closures, fn_traits)]
struct Add(u32);
impl FnOnce<(u32,)> for Add {
type Output = Add;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
Add(self.0 + args.0)
}
}
impl FnOnce<()> for Add {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.0
}
}
fn main() {
dbg!( Add(1)(2)(3)() );
//dbg!( Add() ); // doesn't compile
}
Playground
Although I should note that this likely isn't such a great idea, using an slice/iterator would likely result in cleaner code:
fn main() {
dbg!([1, 2, 3].iter().copied().sum::<u32>());
}
Playground

How do I fix "the method `clone` exists but the following trait bounds were not satisfied" when cloning a struct with generics and a function pointer? [duplicate]

This question already has answers here:
Deriving a trait results in unexpected compiler error, but the manual implementation works
(2 answers)
Closed 2 years ago.
I'm writing a function that will create a menu interface in the terminal. To use the function, it needs to be passed a Vec<menu_option>
#[derive(Clone)]
pub struct menu_option<'a, T> {
pub command: &'a str,
pub description: &'a str,
pub action: menu_option_action<'a, T>,
}
#[derive(Clone)]
pub enum menu_option_action<'a, T> {
sub_menu(Vec<menu_option<'a, T>>),
callback(fn(state: T) -> T),
leave,
}
When I design the menu, it can have multiple levels and there can be repeats of a menu_action. Namely, each layer has a "leave"/"return":
// In my actual code I construct a vector of `menu_option`s
fn example() {
type StateType = i32;
let mut state: StateType = 88;
let leave_option: menu_option<&mut StateType> = menu_option::<&mut StateType> {
command: "l",
description: "leave",
action: menu_option_action::leave,
};
let a = leave_option.clone();
}
error[E0599]: no method named `clone` found for struct `menu_option<'_, &mut i32>` in the current scope
--> src/lib.rs:24:26
|
2 | pub struct menu_option<'a, T> {
| -----------------------------
| |
| method `clone` not found for this
| doesn't satisfy `menu_option<'_, &mut i32>: std::clone::Clone`
...
24 | let a = leave_option.clone();
| ^^^^^ method not found in `menu_option<'_, &mut i32>`
|
= note: the method `clone` exists but the following trait bounds were not satisfied:
`&mut i32: std::clone::Clone`
which is required by `menu_option<'_, &mut i32>: std::clone::Clone`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `clone`, perhaps you need to implement it:
candidate #1: `std::clone::Clone`
How do I fix this?
I tried searching online and couldn't find a solution, at least, not one that worked for me (what I found was old Rust, I think)
I don't know what stops the clone because the only use of the T type is a function pointer which I thought was cloneable.
It works when you implement Clone yourself on menu_option & menu_option_action. By default, since your struct/enum has a type parameter, the macro expansion of the #[derive(Clone)] attribute will restrain the clone implementation for your type to T: Clone.
In your case, not only is this requirement not needed, but it is also very unlikely to be ever respected (e.g. &mut T does not implement Clone). By implementing Clone by hand, you can get rid of the T: Clone requirement and it works!
Note that function pointers implement Copy which is why the menu_option_action::callback(*f) works:
type StateType = i32;
pub struct menu_option<'a, T> {
pub command: &'a str,
pub description: &'a str,
pub action: menu_option_action<'a, T>,
}
impl<'a, T> Clone for menu_option<'a, T> {
fn clone(&self) -> Self {
menu_option {
command: self.command.clone(),
description: self.description.clone(),
action: self.action.clone(),
}
}
}
pub enum menu_option_action<'a, T> {
sub_menu(Vec<menu_option<'a, T>>),
callback(fn(T) -> T),
leave,
}
impl<'a, T> Clone for menu_option_action<'a, T> {
fn clone(&self) -> Self {
match self {
menu_option_action::sub_menu(sub) => menu_option_action::sub_menu(sub.to_vec()),
menu_option_action::callback(f) => menu_option_action::callback(*f),
menu_option_action::leave => menu_option_action::leave,
}
}
}
fn main() {
let mut state: StateType = 88;
let leave_option: menu_option<&mut StateType> = menu_option {
command: "l",
description: "leave",
action: menu_option_action::leave,
};
let a = leave_option.clone();
}

Why does function pointer behaviour differ in Rust depending on the mutability of the function pointer?

When storing raw pointers to functions in structs in Rust, the behaviour of the program can change in unexpected ways depending on the mutability of the raw pointer.
Using const pointers gives the expected result.
The following code can also be viewed on the playground:
type ExternFn = unsafe extern "C" fn() -> ();
unsafe extern "C" fn test_fn() {
println!("Hello!");
}
mod mut_ptr {
use super::{ExternFn, test_fn};
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: *mut ExternFn,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: (&mut (test_fn as ExternFn) as *mut _),
}
}
pub fn call(&self) {
if !self.function.is_null() {
unsafe { (&*self.function)(); }
}
}
}
}
mod const_ptr {
use super::{ExternFn, test_fn};
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: *const ExternFn,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: (&(test_fn as ExternFn) as *const _),
}
}
pub fn call(&self) {
if !self.function.is_null() {
unsafe { (&*self.function)(); }
}
}
}
}
// use const_ptr::FunctionHolder;
use mut_ptr::FunctionHolder;
fn check_holder(holder: &FunctionHolder) -> bool {
let good = FunctionHolder::new();
println!("parameter = {:#?}", holder);
println!("expected = {:#?}", good);
holder == &good
}
fn main() {
let f0 = FunctionHolder::new();
println!("{:?}", f0);
let f1 = FunctionHolder::new();
println!("{:?}", f1);
// uncomment this line to cause a segfault if using the
// mut_ptr version :-(
// f1.call();
assert!(check_holder(&f1));
}
In the const_ptr module, the code behaves as expected: The pointer value stored in the FunctionHolder struct is the same regardless of where the function is called, and using the FunctionHolder::call method calls the function as required.
In the mut_ptr module, there are some unexpected differences:
The FunctionHolder::new method returns a struct holding a different value depending on the function in which it is called,
The FunctionHolder::call method causes a segfault.
fn() -> () is a function pointer. *const fn() -> () and *mut fn() -> () are function pointer pointers.
You want to use much simpler code, which also means there's no difference between the two implementations:
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: Option<ExternFn>,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: Some(test_fn as ExternFn),
}
}
pub fn call(&self) {
if let Some(f) = self.function {
unsafe { f(); }
}
}
}
As mentioned in the comments, taking a mutable reference to a literal value constructs a new value each time:
fn main() {
println!("{:p}", &42);
println!("{:p}", &42);
println!("{:p}", &42);
println!("{:p}", &mut 42);
println!("{:p}", &mut 42);
println!("{:p}", &mut 42);
}
0x55a551c03a34
0x55a551c03a34
0x55a551c03a34
0x7ffd40dbb95c
0x7ffd40dbb9bc
0x7ffd40dbba1c
Immutable references to literals have implicit static promotion:
let a = &42;
// More-or-less
static HIDDEN: i32 = 42;
let a = &HIDDEN;
Mutable references to literals desugar to effectively:
let mut hidden: i32 = 42;
let a = &mut hidden;
By using raw pointers, you lose the support of the borrow checker to point out that your references don't live long enough for the mutable case.
See also:
Why is it legal to borrow a temporary?
Why can I return a reference to a local literal but not a variable?
What are the semantics of mutably borrowing a literal in Rust?

Function refered from the stored in struct does not give the ownership up

I'm writing a algorithm testbench to compare performance in Rust.
I want to store a bunch of function for an algorithm in a struct, and apply those functions to some data.
When I call the function by reference, which stored in the struct, I couldn't figure out the lifetime.
struct Alg<'a, 'b, 'c> {
alg1: &'c Fn(&'a A<'a>, &'b B<'b>) -> usize,
alg2: &'c Fn(&'a A<'a>, &'b B<'b>) -> String,
}
struct A<'a> {
a_str: &'a str,
}
struct B<'b> {
b_str: &'b str,
}
fn concat<'a, 'b>(_a: &'a A<'a>, _b: &'b B<'b>) -> String {
_a.a_str.to_string() + &_b.b_str.to_string()
}
fn length<'a, 'b>(_a: &'a A<'a>, _b: &'b B<'b>) -> usize {
_a.a_str.len() + _b.b_str.len()
}
fn run1<'a, 'b, 'c>(_a: &'a A<'a>, _b: &'b B<'b>, _f_c: &'c Alg<'a, 'b, 'c>) {
println!("{}", &(_f_c.alg1)(_a, _b));
}
fn run2<'a, 'b, 'c>(_a: &'a A<'a>, _b: &'b B<'b>, _f_c: &'c Alg<'a, 'b, 'c>) {
println!("{}", &(_f_c.alg2)(_a, _b));
}
fn main() {
let f_struct = Alg {
alg1: &length,
alg2: &concat,
};
for _i in 0..2 {
let a_str = "ABC";
let a = A { a_str: a_str };
for _j in 0..2 {
let b_str = "BCD";
let b = B { b_str: b_str };
println!("{}", concat(&a, &b)); // This works
println!("{}", (f_struct.alg1)(&a, &b)); // I expect that `concat` or `length` in `f_struct` may finished borrowing `a` or `b' here, as like as `println!("{}",concat(&a,&b))`
//run1(&a,&b,&f_struct);
//run2(&a,&b,&f_struct);
}
}
}
When I run this, I get an error message like:
error[E0597]: `a` does not live long enough
--> src/main.rs:43:44
|
43 | println!("{}", (f_struct.alg1)(&a, &b)); // I expect that `concat` or `length` in `f_struct` may finished borrowing `a` or `b' here, as like as `println!("{}",concat(&a,&b))`
| --------------- ^^ borrowed value does not live long enough
| |
| borrow used here, in later iteration of loop
...
47 | }
| - `a` dropped here while still borrowed
error[E0597]: `b` does not live long enough
--> src/main.rs:43:48
|
43 | println!("{}", (f_struct.alg1)(&a, &b)); // I expect that `concat` or `length` in `f_struct` may finished borrowing `a` or `b' here, as like as `println!("{}",concat(&a,&b))`
| --------------- ^^ borrowed value does not live long enough
| |
| borrow used here, in later iteration of loop
...
46 | }
| - `b` dropped here while still borrowed
What is the difference between println!("{}",concat(&a,&b)) and println!("{}",(f_struct.alg1)(&a,&b))?
I thought that I have to indicate something that the function no more borrows the value with lifetime 'a or 'b, but I couldn't find it from rust-by-example or rust-book.
I've tried to apply coercion like 'c: 'a + 'b, but this seems not to help.
These questions are related, but not so clear to me.
Rust lifetime error
Rust lifetime error expected concrete lifetime but found bound lifetime
Questions about Rust lifetime
Point
I want to store functions in the struct
I could try another way like not to store functions in the struct
But I want to understand the reason when this approach is impossible
Quick solution
You have too many lifetime specifiers. Remove the lifetimes for references in your function parameters. Eg. replace alg1: &'c Fn(&'a A<'a>, &'b B<'b>) -> usize with alg1: &'c Fn(&A<'a>, &B<'b>) -> usize (and similar changes to all functions (playground).
Explanation
First, let's simplify your code a bit and rename some of the lifetimes so that we know which one we are talking about:
struct Alg<'Alg_a, 'Alg_b> {
alg1: &'Alg_b Fn(&'Alg_a A<'Alg_a>) -> usize,
}
struct A<'A_a> {
a_str: &'A_a str,
}
fn length<'L_a>(a: &'L_a A<'L_a>) -> usize {
a.a_str.len()
}
fn main() {
let f_struct = Alg {
alg1: &length,
};
for _i in 0..2 {
let a_str = "ABC";
let a = A { a_str: a_str };
println!("{}", length (&a)); // This works
println!("{}", (f_struct.alg1) (&a)); // This doesn't
}
}
You can check on the playground that this exhibits the same error as your code.
When you call (f_struct.alg1)(&a), the compiler tries to find good values for the lifetimes 'Alg_a and 'Alg_b associated with f_struct. Since f_struct is defined outside the loop, then those lifetimes must be the same for all iterations of the loop. However Alg::alg1 is defined as Fn(&'Alg_a …) which means that 'Alg_a must be the lifetime of the parameter a which is only valid for a single loop iteration. Hence the error.
By not specifying the lifetime of the parameter, I allow the compiler to choose different lifetimes for the parameter a and for 'Alg_a, and in particular to choose a different lifetime for the parameter each time the function is called. So the lifetime for the parameter can be limited to a single loop iteration while 'Alg_a may be longer:
struct Alg<'Alg_a, 'Alg_b> {
alg1: &'Alg_b Fn(&A<'Alg_a>) -> usize,
}
struct A<'A_a> {
a_str: &'A_a str,
}
fn length<'L_a>(a: &A<'L_a>) -> usize {
a.a_str.len()
}
fn main() {
let f_struct = Alg {
alg1: &length,
};
for _i in 0..2 {
let a_str = "ABC";
let a = A { a_str: a_str };
println!("{}", length (&a)); // This works
println!("{}", (f_struct.alg1) (&a)); // Now this does too
}
}
playground
Why does calling length directly work?
When calling length directly, the compiler only needs to determine the lifetime 'L_a and there is nothing that requires this lifetime to last for more than a single loop iteration, so there is no conflict.
Note
As noted by #VikramFugro, this only work because a_str = "ABC" creates a slice with a 'static lifetime which can be shrunk down to 'Alg_a or 'L_a as required. Using a dynamic string (let a_str = String::from("ABC")) does not work. We need to declare alg1 as &'Alg_b for<'F_a> Fn(&A<'F_a>) -> usize instead of using the 'Alg_a lifetime on the Alg struct:
struct Alg<'Alg_b> {
alg1: &'Alg_b for<'F_a> Fn(&A<'F_a>) -> usize,
}
playground
Additionally, Rust 2018 allows us to use an anonymous lifetime '_ instead of the for<'a> … syntax, for example &'Alg_b Fn(&A<'_>) -> usize (playground).

Swift, math functions and protocols

I'm trying to create 2 protocols ArithmeticType and MathematicType that will be used in where clauses of generic operator functions
protocol ArithmeticType {
func +(lhs: Self, rhs: Self) -> Self
func -(lhs: Self, rhs: Self) -> Self
func *(lhs: Self, rhs: Self) -> Self
func /(lhs: Self, rhs: Self) -> Self
}
extension Int : ArithmeticType {
}
extension Double : ArithmeticType {
}
extension Float : ArithmeticType {
}
ArithmeticType works as expected and either Int, Float and Double conform to it. However the following fails
import Darwin
protocol MathematicType {
func sin(x: Self) -> Self
}
extension Double : MathematicType {
}
extension Float : MathematicType {
}
on console output of the playground I read:
Playground execution failed: <EXPR>:35:1: error: type 'Double' does not conform to protocol 'MathematicType'
extension Double : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Double -> Self'
func sin(x: Self) -> Self
^
<EXPR>:39:1: error: type 'Float' does not conform to protocol 'MathematicType'
extension Float : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Float -> Self'
func sin(x: Self) -> Self
^
I would like that math functions behave like the operators above. Is there any way?
== EDIT:
Now I realize that trying to simplify my question was a bad idea. the context is this class (vector of optional values)
class Vector<T> {
var data=[T?]()
init(fromArray: Array<T>) {
for i in fromArray {
data.append(i)
}
}
init() {
}
init(count: Int){
for i in 0..<count {
data.append(nil)
}
}
init(count: Int, repeatedValue: T) {
for i in 0..<count {
data.append(repeatedValue)
}
}
func count() -> Int {
return data.count
}
func append(newElement: T?) {
data.append(newElement)
}
subscript(index: Int) -> T? {
let i = index>0 ? index % count() : -index % count()
return data[i]
}
}
outside of it I defined a generic function for the + operator
func +<T where T: ArithmeticType>(left: Vector<T>, right: Vector<T>) -> Vector<T> {
let resultCount = max(left.count(),right.count())
var result = Vector<T>()
for i in 0..<resultCount {
if left[i] != nil && right[i] != nil {
result.append(left[i]!+right[i]!)
}
else {
result.append(nil)
}
}
return result
}
that works as expected, however when I tried to define a generic sin function as
func sin<T where T : FloatingPointType>(x: Vector<T>) -> Vector<T>{
var result = Vector<T>()
for i in 0..<x.count() {
if let o = x[i] {
result.append(sin(o))
}
else {
result.append(nil)
}
}
return result
}
I got "could not find an overload of sin that accepts the supplied arguments"
then my attempt with MathemticType trying to mimic what I already done for + operator
(ArithmeticType was inspired from IntegerAritmeticType source found by command clicking on import swift more than my knowledge of what I was doing)
== UPDATE
If I write a specialized function only for Double
func sin(x: Vector<Double>) -> Vector<Double>{
var result = Vector<Double>()
for i in 0..<x.count() {
if let o = x[i] {
result.append(Darwin.sin(o))
}
else {
result.append(nil)
}
}
return result
}
it works as expected.
So the question may become "How can I generalize this to either Double and Float" ?
The compiler error is because you declared sin() as a method of the MathematicType protocol, and then declared that Double implements MathematicType, but didn't actually write the sin() method.
extension Double {
func sin(x: Double) -> Double {
return Darwin.sin(x)
}
}
I don't think that's what you want, though, is it? You want to be able to write this:
let myAngle = 3.14159
let sineValue = myAngle.sin()
If that's the case, your protocol and extension would need to look like this:
protocol MathematicType {
func sin() -> Self
}
extension Double : MathematicType {
func sin() -> Double {
return Darwin.sin(self)
}
}
Your MathematicType protocol, and your declarations of conformance to it in Float and Double extensions, say that Float and Double should provide sin as an instance method. That is, you're saying one should be able to write code like:
let zero = 0.0 // inferred type Double
zero.sin(1.5707963268) // returns about 1.0
Notice that invocation of sin isn't actually related to the value of zero, so this probably isn't the behavior you want.
You're probably looking to have sin be a free function, so you can just write:
sin(1.5707963268)
Right?
In that case, your work is already done... the standard library defines both:
func sin(x: Double) -> Double
func sin(x: Float) -> Float
If what you actually want is for your MathematicType to be usable as a generic parameter, meaning "a type you can take the sine of", you'll need a generic sin function. Something like this (quick kludgy solution, there's probably better):
func sine<T: FloatingPointType>(x: T) -> T {
if let v = x as? Double {
return sin(v) as T
}
if let v = x as? Float {
return sin(v) as T
}
fatalError("unknown FloatingPointType")
}
(Notice also that there's already a protocol that both Float and Double conform to, so I've used that in the example.)
I think the issue is that operator requirements and instance method requirements are different, even though they syntactically look similar. Operators are always defined at the global level, so an operator requirement is a requirement on an operator at the global level. On the other hand, instance method requirements are requirements on instance methods. There is no way to specify a global function requirement.