What is the proper OOP architecture for Rust? [closed] - oop

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have a program that written in python and uses classes.
i wanna convert the same structure to Rust but we don't have classes in rust instead we have (impl & strcut). so that makes me confuse that how can implement the same OOP structure as python in Rust !
Please bring an example for the architecture in Rust so i can have it as reference.
i've tried reading this tutorial but i didn't get what i want.
https://stevedonovan.github.io/rust-gentle-intro/object-orientation.html
My existing program example:
file: main.py
import my_lib
class main(object):
def __init__(self):
print('main > init')
def start(self):
my_lib.run()
if __name__ == "__main__":
main()
file: /lib/my_lib.py
def run():
print('running...')

The python code example you give doesn't make use of many object-oriented features, but it's not too hard to translate into Rust:
file: main.rs
mod my_lib; // This instructs Rust to look for `my_lib.rs` and import it as `my_lib`.
mod main {
pub fn init() {
println!("main > init");
}
pub fn start() {
super::my_lib::run() // We have to add super:: to talk about things that were imported in the parent module rather than the `main` module itself, like `my_lib`
}
}
fn main() { // This is the function that starts your program. It's always called `main`.
main::init()
}
file: my_lib.rs
pub fn run() {
println!("running...")
}
Notably, this isn't quite equivalent to your python code, because main is a module instead of a class. If you intend to use its self instance to store data or any persistent state, the example would look different (main would be a struct, and its methods would be in an impl block.) I can edit my answer if that's closer to what you're looking for.

Related

Kotlin function unresolved reference [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm working on this thing that has some function callings like this:
fun f1(){
// does some stuff
f2();
}
fun f2(){
// does some stuff
f1();
}
This is a simplification of what my code looks like (it doesn't go for an infinity loop). My problem is that it returns the error that f2 is unreferenced. I tried searching this online but the only solutions I saw from people asking where to move the function above the funciton call, but that wouldn't work for me since my other function calls that one as well and moving the f2 above f1 would just make f1 unresolved when f1 is called from f2.
I also tried the function declaration thing c and c++ has but it lead to errors saying I have ambiguous function definitions and that they're expecting a function body in the function declaration.
Thanks.
I am assuming you are trying to define both functions inside the same local scope and getting an "Unresolved reference" Kotlin compiler error.
If that is your case and you cannot refactor your flow in a better way, then you can declare one of the functions as a nullable variable and assign it later.
Your code would then become
var f2: (() -> Unit)? = null
fun f1() {
// does some stuff
// Option 1: wont get invoked if f2 is null when this line is executed
f2?.invoke()
// Option 2: will always try to get invoked, but if f2 is null when this line is executed,
// it will throw a NullPointerException
f2!!.invoke()
}
f2 = {
// does some stuff
f1()
}

What are Local declarations for : variables, functions and classes In Kotlin? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
So i started learning kotlin for android development.
But when i get to the visibility topic i met this note stating:
Local declarations
Local variables, functions and classes can not have visibility modifiers.
What are Local declarations in Kotlin ?
I asked you here witch means i already did a search on the internet but the only results i have got they were about java and other programming languages and i don't want to mix up things so i can avoid confusion.
Thanks very much in advance
Local declarations are declarations placed inside a body of a function (or a constructor, an init block, or a property accessor).
These declarations can only be referenced inside the lexical scope where they are declared:
fun foo() {
if (Random().nextInt() % 2 == 0) {
fun bar() {
println("bar")
}
bar() // OK
} else {
bar() // Error: unresolved reference
}
}
Consequently, these declarations can never be used outside the body, and therefore visibility modifiers (which normally control whether a declaration is accessible outside the type or the file) are meaningless for local declarations.
Local declarations can be used for entities that have meaning only inside a body of the function and not anywhere else, or should not be used anywhere else.
An example of a valid use case for local declarations is a data class for intermediate values of a calculation:
fun getAndSaveEmails(people: List<Person>) {
data class PersonWithEmail(
val person: Person,
val email: String
)
val peopleWithEmails = people.map { PersonWithEmail(it, requestEmail(it)) }
peopleWithEmails.forEach { save(it.person, it.email) }
}

Is String a valid Error type when it can be reported immediately in stdout? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
The community reviewed whether to reopen this question 10 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I recently implemented basic mechanics of a game of chess and used the Result<T, E> type for methods collecting human input, since it may be invalid. However, I'm not sure about what type I should pick for the possible error (E).
I have gathered that introducing new types is considered a good practice when building a library. However, when the Result can be handled immediately and the Err reported in stdout, isn't it simpler to just return Result<T, String>s or Result<T, &str>s (or Result<T, Cow<str>>s if both can occur)?
Consider the following case:
pub fn play() {
let mut game = Game::new();
loop {
match game.turn() {
Ok(()) => { game.turn += 1 }
Err(e) => println!("{}", e)
}
}
}
The game is played in the terminal and any input errors can immediately be reported. Is there any added value to introducing a custom error type in this case?
This is a rather broad question and there is no clear "right" or "wrong" answer.
It's important to note in your example, that strings carry very little easily accessible semantic information. Sure, you might be able to extract all semantic information by parsing the string, but this is really the wrong approach. Therefore, most bigger libraries or applications use error types that carry more semantic information to allow for easy error handling.
In your case, strings are probably fine, if you will print them immediately anyway. But there is a neat little trick in order to make at least the function signatures a bit more future proof: return Box<Error>.
The Error trait is a nice abstraction over errors. Pretty much every error type implements this trait. With the ? operator and the Into trait, it's possible to handle most errors with ease. Furthermore: there are a few type conversion impls for strings and Box<Error>. This allows to return strings as errors:
use std::error::Error;
fn foo() -> Result<(), Box<dyn Error>> {
std::fs::File::open("not-here")?; // io::Error
Err("oh noooo!")?; // &str
Err("I broke it :<".to_owned())?; // String
Err("nop".into())
}
fn main() {
println!("{}", foo().unwrap_err());
}
See the working demo.
Edit: please note, that Box<Error> carries less semantic information than another concrete error type like io::Error. So it's not a good idea to always return Box<Error>! It's just a better approach in your situation :)
Edit 2: I've read a lot on error handling models recently, which changed my opinion a bit. I still think this answer is pretty much true. However, I think it's by far not as easy as I formulated it here. So just keep in mind that this answer doesn't suit as general guide at all!

Why Dart Team does not follow their own style-guide? Or we all also must follow this guide? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I cannot understand for whom Dart style-guide was written?
Dart Style Guide
Term PREFER form this guide:
"PREFER guidelines are practices that you should follow. However, there may be circumstances where it makes sense to do otherwise. Just make sure you understand the full implications of ignoring the guideline when you do"
Now one of the main practices that often discussed and, of course, we should follow it:
PREFER using var without a type annotation for local variables.
In short words, use type annotation in function body not recommended (except some very specific situations).
But when I look into source code of the Dart SDK I often see just the opposite.
Just one sample from many other similar.
runtime/lib/collection_patch.dart
Example:
void operator []=(K key, V value) {
int hashCode = key.hashCode;
List buckets = _buckets;
int length = buckets.length;
int index = hashCode & (length - 1);
_HashMapEntry entry = buckets[index];
while(entry != null) {
if (hashCode == entry.hashCode && entry.key == key) {
entry.value = value;
return;
}
entry = entry.next;
}
_addEntry(buckets, index, length, key, value, hashCode);
}
Why Dart team used type annotations for local variables instead of var?
I cannot understand for whom Dart style-guide was written?
It was written for Dart programmers. Why? Because..
As we build up an ecosystem of Dart code, it’s helpful if it follows a consistent coding style. A dedicated style guide for Dart helps us make the most of the features unique to the language and makes it easier for users to collaborate.
And it is up to each programmer or team whether or not to follow these guidelines, which are just a suggestion.

Ada: packaging concepts [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
This is a follow up of my earlier post here:
Ada: Understanding private types and understanding packaging
An implementation for the Rectangular type was made using one implementation i.e. Rectangular_Method_1 and a specification file and a body file were required for this implementation.
If we want to have another implementation Rectangular_Method_2 available to the user then the main file rectangular_Form.ads can be changed to
-- with Rectangular_Method_1;
-- package Rectangular_Form renames Rectangular_Method_1;
with Rectangular_Method_2;
package Rectangular_Form renames Rectangular_Method_2;
Questions
Is this the right way in software engineering to allow for another implementation in that the test file test_rectangular_form.adb remains the same for a different implementation?
If we create a second implementation Rectangular_Method_2, Is there a need to create a separate specification file in addition to the compulsory new body for this new implementation? There is the need however to provide the same procedures/functions for Vector_Basis_r, Set_Horz, Get_Horz etc in the new implementation so that we can call them in test_rectangular_form.adb.
Thanks...
If you use GNAT, you can use GPR files for the project. In there you can change the filename for specific packages, for example:
for Specification (Rectangular_Form) use "Rectangular_Method_1.ads";
for Implementation (Rectangular_Form) use "Rectangular_Method_1.adb";
you can even set this depending on an environment variable.
If your spec files all should look the same, you can use a Rectangular_Form.ads and only use the Implementation line from above.
An example GPR file could look like this:
project Example is
type Methods is ("normal", "something_else");
Method : Methods := external ("METHOD", "normal");
package Naming is
case Method is
when "normal" =>
for Implementation ("Example") use "example_normal.adb";
when "something_else" =>
for Implementation ("Example") use "example_something.adb";
end case;
end Naming;
end Example;
Then, you can use gnatmake -P example.gpr to compile it depending on your METHOD variable, or using a -XMETHOD=... parameter for gnatmake or just use the provided default value.
The example_*.adb should all contain the body of the package Example, not Example_Normal, etc..
Another way to do this would be to use tagged types.
package Rectangular is
type Instance is abstract tagged private;
procedure Vector_Basis_r (A : in Long_Float; D : out Instance);
procedure Set_Horz (R : in out Instance; H : Long_Float);
function Get_Horz (R : Instance) return Long_Float;
private
type instance is tagged null record;
end Rectangular;
with Rectangular;
package Rectangular_Method_1 is
type Instance is new Rectangular.Instance with private;
...
private
type Instance is new Rectangular.Instance with
record
Horz, Vert: Long_Float;
end record;
end Rectangular_Method_1;
(similar implementation for Rectangular_Method_2).
Then I believe you can write your code that uses it this way:
with Rectangular_Method_1;
with Rectangular_Method_2;
...
-- My_Rectangle : Rectangular_Method_1.Instance;
My_Rectangle : Rectangular_Method_2.Instance;
My_Rectangle.Set_Horiz(Whatever_Value);
...
In other words, all you'd have to change when switching between the two is the type names. Your client could even get rid of those changes by using a single subtype at the top.
subtype Rectangle_Instance is Rectangular_Method_2.Instance;
This would also give you the ability to move common code/fields up into the base class (package), which I think is sort of what you were after.