Vlang module calls confusion - module

Basics
| main.v
| beta.v
|
|__ parent
| mod1.v
|
|__ child
| mod2.v
Codes:
main.v
import parent
import parent.child as pc
fn main(){
parent.name_parent()
pc.name_child()
}
mod1.v
module parent
pub fn name_parent(){
println('Parent!!!')
}
mod2.v
module child
pub fn name_child(){
println('child!!!')
}
beta.v
pub fn beta_test(){
println('Beta!!!')
}
Need some insight on the module structure:
Error when I run main.v to access child directory.
*error: unknown function: parent.child.name_child*
How to access beta.v function from main.v ?

Related

Why do lines 14 and 21 not compile (for my Kotlin function)?

I have a function named collectCustomizerFunctions which should create a MutableList<KCallable<*>> of all the functions of a specified class and its sub-classes which are annotated with CustomizerFunction.
Recursively, customizerFuns (the MutableList<KCallable<*>>) should have all of the "cutomizer functions" added to it.
When I try to build my Gradle project, it fails with two exceptions:
e: collectCustomizerFuns.kt:14:33 Type inference failed. The value of the type parameter T should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly.
e: collectCustomizerFuns.kt:21:30 Type mismatch: inferred type is Any but CapturedType(*) was expected
Here is my code:
3 | import kotlin.reflect.KClass
4 | import kotlin.reflect.KCallable
5 | import kotlin.reflect.full.allSuperclasses
6 |
7 | #Utility
8 | public tailrec fun <T: Any> collectCustomizerFuns(
9 | specClass: KClass<T>,
10 | customizerFuns: MutableList<KCallable<*>>
11 | ): Unit {
12 | // add annotated functions of this class
13 | for (member in specClass.members) {
14 | if (CustomizerFunction::class in member.annotations) { <--- ERROR
15 | customizerFuns.add(member)
16 | } else {}
17 | }
18 |
19 | // add annotated functions of all super-classes
20 | for (superclass in specClass.allSuperclasses) {
21 | collectCustomizerFuns<Any>(superclass, customizerFuns) <--- ERROR
22 | }
23 | }
I have been trying to fix these bugs for a while now, and would appreciate any help!
Also, please provide any constructive criticism you want regarding this function, it would help a lot!
For the first error, member.annotations returns List<Annotation>. You have to fetch actual classes of these annotations.
For the second error, remove the type where you call collectCustomizerFuns. Let kotlin infers the type by itself :).
So try this:
public tailrec fun <T: Any> collectCustomizerFuns(
specClass: KClass<T>,
customizerFuns: MutableList<KCallable<*>>
) {
// add annotated functions of this class
for (member in specClass.members) {
if (CustomizerFunction::class in member.annotations.map { it.annotationClass }) {
customizerFuns.add(member)
} else {
}
}
// add annotated functions of all super-classes
for (superclass in specClass.allSuperclasses ) {
collectCustomizerFuns(superclass, customizerFuns)
}
}
By the way, you can remove Unit from the method signature.

How do I use a module from multiple unit test modules?

I have two modules with unit tests and I want to access constants/variables with expected test results from both of those modules.
File: src/lib.rs
mod other;
#[cfg( test )]
mod tests {
mod expected;
use crate::tests::expected::FOUR;
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!( result, FOUR );
}
}
File: src/other.rs
#[cfg( test )]
mod tests {
use crate::tests::expected::EIGHT;
#[test]
fn it_works() {
let result = 4 + 4;
assert_eq!( result, EIGHT );
}
}
File src/tests/expected.rs
pub const FOUR: i32 = 4;
pub const EIGHT: i32 = 8;
From src/lib.rs I can access the constants within expected.rs. But this is not true from src/other.rs. I get the follwing error:
error[E0603]: module `expected` is private
--> src/other.rs:3:20
|
3 | use crate::tests::expected::EIGHT;
| ^^^^^^^^ private module
|
note: the module `expected` is defined here
--> src/lib.rs:5:2
|
5 | mod expected;
| ^^^^^^^^^^^^^
I have no idea how to make expected public. Where would I place expected.rs or how would I make it accessible from the test code of other modules of the library?

Why Isn't This Module Visible?

I'm coding a hash in Rust for practice. The code looks like this:
pub fn get_fnv1a32(to_hash:&str) -> u32{
const OFFSET_BASIS:u32 = 2_166_136_261;
const PRIME:u32 = 16_777_619;
if !to_hash.is_empty(){
let mut hash = OFFSET_BASIS;
for b in to_hash.bytes(){
hash = hash ^ (b as u32);
hash = hash.wrapping_mul(PRIME);
}
hash
}
else
{
0
}
}
And this is the code I'm trying to use to test this:
mod fnv;
#[cfg(test)]
mod tests {
#[test]
fn get_correct_hash(){
assert_eq!(0x7a78f512, fnv::get_fnv1a32("Hello world!"));
}
#[test]
fn hash_handles_empty_string_correctly(){
assert_eq!(0, fnv::get_fnv1a32(""));
}
}
The test code is in lib.rs and the get_fnv1a32 function is in fnv.rs. They're both in the same directory. But when I try to run cargo test I keep getting these messages:
Compiling hashes v0.1.0 (U:\skunkworks\rust\hashes)
warning: function is never used: `get_fnv1a32`
--> src\fnv.rs:1:8
|
1 | pub fn get_fnv1a32(to_hash:&str) -> u32{
| ^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
error[E0433]: failed to resolve: use of undeclared type or module `fnv`
--> src\lib.rs:7:32
|
7 | assert_eq!(0x7a78f512, fnv::get_fnv1a32("Hello world!"));
| ^^^ use of undeclared type or module `fnv`
error[E0433]: failed to resolve: use of undeclared type or module `fnv`
--> src\lib.rs:12:23
|
12 | assert_eq!(0, fnv::get_fnv1a32(""));
| ^^^ use of undeclared type or module `fnv`
error: aborting due to 2 previous errors
I can't figure out what I'm doing wrong. I tried changing the mod fnv; line at the top to pub mod fnv; and that gets rid of the dead code warning but it doesn't fix the two errors. What do I need to do to get the get_fnv1a32 function to be visible in the lib.rs file?
Not that I would think it would matter but the version of rustc is rustc 1.41.0 (5e1a79984 2020-01-27)
The test module is separate from the outer module. Add
use super::*;
or an equivalent statement like use crate::fnv inside the tests module to make the fnv module visible.

Why do I get "the method exists but the following trait bounds were not satisfied" when extending Result for failure types?

I'm trying to add a more concise version of the failure crate's .with_context(|e| format!("foo: {}", e)) to my code. Like this playground:
use failure::{Context, Fail, ResultExt}; // 0.1.5
/// Extension methods for failure `Result`.
pub trait ResultContext<T, E> {
/// Wraps the error type in a context type generated by looking at the
/// error value. This is very similar to `with_context` but much more
/// concise.
fn ctx(self, s: &str) -> Result<T, Context<String>>;
}
impl<T, E> ResultContext<T, E> for Result<T, E>
where
E: Fail,
{
fn ctx(self, s: &str) -> Result<T, Context<String>> {
self.map_err(|failure| {
let context = format!("{}: {}", s, failure);
failure.context(context)
})
}
}
pub fn foo() -> Result<i32, failure::Error> {
Ok(5i32)
}
pub fn main() -> Result<(), failure::Error> {
// This works.
let _ = foo().with_context(|_| "foo".to_string())?;
// This doesn't.
foo().ctx("foo")?
}
I get the following error:
error[E0599]: no method named `ctx` found for type `std::result::Result<i32, failure::error::Error>` in the current scope
--> src/main.rs:31:11
|
31 | foo().ctx("foo")?
| ^^^
|
= note: the method `ctx` exists but the following trait bounds were not satisfied:
`std::result::Result<i32, failure::error::Error> : ResultContext<_, _>`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `ctx`, perhaps you need to implement it:
candidate #1: `ResultContext`
I can't work out why. I more or less copied the existing with_context code.
As the compiler tells you, Result<i32, failure::error::Error> doesn't implement ResultContext<_, _>. You have added a bound to your implementation:
where
E: Fail,
But failure::Error doesn't implement failure::Fail:
use failure; // 0.1.5
fn is_fail<F: failure::Fail>() {}
pub fn main() {
is_fail::<failure::Error>();
}
error[E0277]: the trait bound `failure::error::Error: std::error::Error` is not satisfied
--> src/main.rs:6:5
|
6 | is_fail::<failure::Error>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `failure::error::Error`
|
= note: required because of the requirements on the impl of `failure::Fail` for `failure::error::Error`
note: required by `is_fail`
--> src/main.rs:3:1
|
3 | fn is_fail<F: failure::Fail>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You will need to alter your bounds or your type.

Use trait from submodule with same name as struct

Trying to compile the following Rust code
mod traits {
pub trait Dog {
fn bark(&self) {
println!("Bow");
}
}
}
struct Dog;
impl traits::Dog for Dog {}
fn main() {
let dog = Dog;
dog.bark();
}
gives the error message
error[E0599]: no method named `bark` found for type `Dog` in the current scope
--> src/main.rs:15:9
|
9 | struct Dog;
| ----------- method `bark` not found for this
...
15 | dog.bark();
| ^^^^
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
1 | use crate::traits::Dog;
|
If I add use crate::traits::Dog;, the error becomes:
error[E0255]: the name `Dog` is defined multiple times
--> src/main.rs:11:1
|
1 | use crate::traits::Dog;
| ------------------ previous import of the trait `Dog` here
...
11 | struct Dog;
| ^^^^^^^^^^^ `Dog` redefined here
|
= note: `Dog` must be defined only once in the type namespace of this module
If I rename trait Dog to trait DogTrait, everything works. How can I use a trait from a submodule that has the same name as a struct in my main module?
You could rename the trait when importing it to get the same result without renaming the trait globally:
use traits::Dog as DogTrait;
The compiler now even suggests this:
help: you can use `as` to change the binding name of the import
|
1 | use crate::traits::Dog as OtherDog;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
documentation
If you don't wish to import both (or can't for whatever reason), you can use Fully Qualified Syntax (FQS) to use the trait's method directly:
fn main() {
let dog = Dog;
traits::Dog::bark(&dog);
}