I am trying some simple code, which I found on natashatherobot.com.
var str = "Hello, playground"
let rangeOfHello = Range(start: str.startIndex, end: advance(str.startIndex, 5))
let helloStr = str.substringWithRange(rangeOfHello)
return helloStr
It works fine when I try it in Playgrounds:
But when I try using it in my Xcode project it gives me a compilation error:
Any ideas why this is happening?
In your function declaration you are saying that it returns a void, but you are trying to return a string, You need to add the -> String in the end of your function to match what you are trying to do
your function:
func getStringBetween(startString: String, endString: String) -> ()
shoud be:
func getStringBetween(startString: String, endString: String) -> String
You did not specify the return type of your func:
func getStringBetween(startString: String, endString: String) -> String {
The problem is the method getStringBetween(:endString:), which you defined in your extension for String.
This method does not define a return type (there's no -> Type after the parameter list). Therefore the implicit return type is Void, so your method could be written as:
func getStringBetween(startString: String, endString: String) -> Void
In Swift the type Void is equivalent to an empty tuple ().
The problem is therefore that Swift expects a return type of Void denoted by (), but you're returning a String.
This problem is easily fixed by adding the return type String to the declaration of your method:
func getStringBetween(startString: String, endString: String) -> String
Side Note:
When writing return, without a specification of what is to be returned, Swift automatically returns ().
Related
I have a ref object type and would like to iterate over all of its fields and echo them out.
Here an example of what I want:
type Creature* = ref object
s1*: string
s2*: Option[string]
n1*: int
n2*: Option[int]
n3*: int64
n4*: Option[int64]
f1*: float
f2*: Option[float]
b1*: bool
b2*: Option[bool]
var x = Creature(s1: "s1", s2: some("s2"), n1: 1, n2: some(1), n3: 2, n4: some(2.int64), f1: 3.0, f2: some(3.0), b1: true, b2: some(true))
for fieldName, fieldValue in x.fieldPairs:
echo fieldName
However, doing so causes this compiler error:
Error: type mismatch: got <Creature>
but expected one of:
iterator fieldPairs[S: tuple | object; T: tuple | object](x: S; y: T): tuple[
key: string, a, b: RootObj]
first type mismatch at position: 1
required type for x: S: tuple or object
but expression 'x' is of type: Creature
iterator fieldPairs[T: tuple | object](x: T): tuple[key: string, val: RootObj]
first type mismatch at position: 1
required type for x: T: tuple or object
but expression 'x' is of type: Creature
expression: fieldPairs(x)
Going through the documentation, there appear to be no iterators for ref object types, only for object types. If that's the case, then how do you iterate over ref object types?
If you want to use iterators, you need to de-reference the ref-type that you want to iterate over! This may also apply to any other proc that expects an object parameter, but that you want to use with a ref object instance.
In nim, the de-referencing operator is [].
So in order to work, the instance x of the ref object type Creature needs to be de-referenced before iterating over it:
for fieldName, fieldValue in x[].fieldPairs:
echo fieldName
This will also work with any proc you write, for example like this:
proc echoIter(val: object) =
for fieldName, fieldValue in val.fieldPairs:
echo fieldName
echoIter(x[])
I need to create a struct type for passing to an external class that is not under my control. That class requires that my struct type has a public default constructor. I need it to have a function type as a member.
The following produces error FS0001: A generic construct requires that the type 'MyStruct' have a public default constructor:
[<Struct>]
type MyStruct =
val callBack: unit -> unit
new(cb: unit -> unit) = { callBack = cb }
type ExternalClass<'T when 'T : (new : unit -> 'T) and 'T : struct> () =
member val something = new 'T()
let c = new ExternalClass<MyStruct>()
This works fine if the type of the member is changed from unit -> unit to int.
I've tried using a DefaultValue attribute, which according to the docs should work fine on a function member, but this produces two errors: error FS0765: Extraneous fields have been given values and error FS0696: This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.
How can I create a suitable type to meet the external class's constraint?
The problem here is that the type unit -> unit does not have a default value. Here's a shorter repro:
[<Struct>]
type MyStruct =
val callBack: unit -> unit
let s = MyStruct()
You get an error on the last line saying: The default, zero-initializing constructor of a struct type may only be used if all the fields of the struct type admit default initialization
The type unit -> unit doesn't admit default initialization. It must have a value of function type, and there is no such thing as "default" function value.
This is how structs in .NET work: every struct always has a default constructor, and the programmer doesn't get to implement it. Instead, the runtime initializes all fields with their default values. The idea behind this is to make allocating arrays or structs very cheap: you just zero out a memory block, and voila!
So by this logic, your callBack field must be zero-outable, but it can't be, because in F# function-typed variables can't be null.
It works fine with int, because int does indeed have a default value of zero.
Now, a "good" solution would depend on what it is you're actually trying to do. But in the absence of that information, I can suggest a couple of local workarounds.
First option - make the field have type obj (so its default value would be null) and provide a safe-ish accessor that would return an option:
[<Struct>]
type MyStruct =
val private callBack: obj
member this.Callback with get() = this.callBack |> Option.ofObj |> Option.map (fun o -> o :?> (unit -> unit))
new(cb: unit -> unit) = { callBack = cb }
The Callback accessor property would then return a (unit -> unit) option, which would be Some if the function was initialized or None if it wasn't:
> MyStruct().Callback;;
val it : (unit -> unit) option = None
> MyStruct(fun() -> ()).Callback;;
val it : (unit -> unit) option = Some <fun:it#10>
Second option - wrap the callback in a nullable type:
[<AllowNullLiteral>]
type ACallback(cb : unit -> unit) =
member val Callback = cb with get
[<Struct>]
type MyStruct =
val callBack: ACallback
new(cb: unit -> unit) = { callBack = ACallback cb }
Then:
> MyStruct().callBack;;
val it : ACallback = <null>
> MyStruct(fun() -> ()).callBack;;
val it : ACallback = FSI_0006+ACallback {Callback = <fun:it#30-1>;}
This (arguably) provides a bit more type safety at the expense of an extra allocation.
Plus, there is a possibility of getting a null, but if that's a problem, you can wrap that in an option-typed accessor too:
[<Struct>]
type MyStruct =
val private callBack: ACallback
member this.Callback with get() = this.callBack |> Option.ofObj |> Option.map (fun c -> c.Callback)
new(cb: unit -> unit) = { callBack = ACallback cb }
> MyStruct().Callback;;
val it : (unit -> unit) option = None
> MyStruct(fun() -> ()).Callback;;
val it : (unit -> unit) option = Some <fun:it#38-2>
package main
import "fmt"
type TT struct {
a int
b float32
c string
}
func (t *TT) String() string {
return fmt.Sprintf("%+v", *t)
}
func main() {
tt := &TT{3, 4, "5"}
fmt.Printf(tt.String())
}
The code can work well. But if I change the String method as in the following, it will cause dead loop. The difference is that the *t is replaced with t. Why?
func (t *TT) String() string {
return fmt.Sprintf("%+v", t)
}
Because the fmt package checks if the value being printed has a String() string method (or in other words: if it implements the fmt.Stringer interface), and if so, it will be called to get the string representation of the value.
This is documented in the fmt package doc:
[...] If an operand implements method String() string, that method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).
Here:
return fmt.Sprintf("%+v", *t)
You are passing a value *t of type TT to the fmt package. If the TT.String() method has a pointer receiver, then the method set of the type TT does not include the String() method, so the fmt package will not call it (only the method set of *TT includes it).
If you change the receiver to non-pointer type, then the method set of the type TT will include the String() method, so the fmt package will call that, but this is the method we're currently in, so that's an endless "indirect recursion".
Prevention / protection
If for some reason you do need to use the same receiver type as the type of the value you pass to the fmt package, an easy and common way to avoid this / protect from it is to create a new type with the type keyword, and use type conversion on the value being passed:
func (t TT) String() string {
type TT2 TT
return fmt.Sprintf("%+v", TT2(t))
}
Try this on the Go Playground.
But why does this work? Because the type keyword creates a new type, and the new type will have zero methods (it does not "inherit" the methods of the underlying type).
Does this incur some run-time overhead? No. Quoting from Spec: Type declarations:
Specific rules apply to (non-constant) conversions between numeric types or to and from a string type. These conversions may change the representation of x and incur a run-time cost. All other conversions only change the type but not the representation of x.
Read more about this here: Does convertion between alias types in Go create copies?
Note: this question contains deprecated pre-1.0 code! The answer is correct, though.
To convert a str to an int in Rust, I can do this:
let my_int = from_str::<int>(my_str);
The only way I know how to convert a String to an int is to get a slice of it and then use from_str on it like so:
let my_int = from_str::<int>(my_string.as_slice());
Is there a way to directly convert a String to an int?
You can directly convert to an int using the str::parse::<T>() method, which returns a Result containing the int.
let my_string = "27".to_string(); // `parse()` works with `&str` and `String`!
let my_int = my_string.parse::<i32>().unwrap();
You can either specify the type to parse to with the turbofish operator (::<>) as shown above or via explicit type annotation:
let my_int: i32 = my_string.parse().unwrap();
Since parse() returns a Result, it will either be an Err if the string couldn't be parsed as the type specified (for example, the string "peter" can't be parsed as i32), or an Ok with the value in it.
let my_u8: u8 = "42".parse().unwrap();
let my_u32: u32 = "42".parse().unwrap();
// or, to be safe, match the `Err`
match "foobar".parse::<i32>() {
Ok(n) => do_something_with(n),
Err(e) => weep_and_moan(),
}
str::parse::<u32> returns a Result<u32, core::num::ParseIntError> and Result::unwrap "Unwraps a result, yielding the content of an Ok [or] panics if the value is an Err, with a panic message provided by the Err's value."
str::parse is a generic function, hence the type in angle brackets.
If you get your string from stdin().read_line, you have to trim it first.
let my_num: i32 = my_num.trim().parse()
.expect("please give me correct string number!");
With a recent nightly, you can do this:
let my_int = from_str::<int>(&*my_string);
What's happening here is that String can now be dereferenced into a str. However, the function wants an &str, so we have to borrow again. For reference, I believe this particular pattern (&*) is called "cross-borrowing".
You can use the FromStr trait's from_str method, which is implemented for i32:
let my_num = i32::from_str("9").unwrap_or(0);
Yes, you can use the parse method on a String to directly convert it to an integer lik so:
let my_string = "42".to_string();
let my_int = my_string.parse::<i32>().unwrap();
The parse method returns a Result object, so you will need to handle the case where the string cannot be parsed into an integer. You can use unwrap as shown above to get the value if the parse was successful, or it will panic if the parse failed.
Or you can use the match expression to handle the success and failure cases separately like so:
let my_string = "42".to_string();
let my_int = match my_string.parse::<i32>() {
Ok(n) => n,
Err(_) => {
println!("Failed to parse integer");
0
},
};
FYI, the parse method is available for any type that implements the FromStr trait, which includes all of the integer types (e.g. i32, i64, etc.) as well as many other types such as f32 and bool.
Well, no. Why there should be? Just discard the string if you don't need it anymore.
&str is more useful than String when you need to only read a string, because it is only a view into the original piece of data, not its owner. You can pass it around more easily than String, and it is copyable, so it is not consumed by the invoked methods. In this regard it is more general: if you have a String, you can pass it to where an &str is expected, but if you have &str, you can only pass it to functions expecting String if you make a new allocation.
You can find more on the differences between these two and when to use them in the official strings guide.
So basically you want to convert a String into an Integer right!
here is what I mostly use and that is also mentioned in official documentation..
fn main() {
let char = "23";
let char : i32 = char.trim().parse().unwrap();
println!("{}", char + 1);
}
This works for both String and &str
Hope this will help too.
What's the proper way to check if a string is empty or blank for a) &str b) String? I used to do it by "aaa".len() == 0, but there should another way as my gut tells me?
Both &str and String have a method called is_empty:
Documentation for &str::is_empty
Documentation for String::is_empty
This is how they are used:
assert_eq!("".is_empty(), true); // a)
assert_eq!(String::new().is_empty(), true); // b)
Empty or whitespace only string can be checked with:
s.trim().is_empty()
where trim() returns a slice with whitespace characters removed from beginning and end of the string (https://doc.rust-lang.org/stable/std/primitive.str.html#method.trim).
Others have responded that Collection.is_empty can be used to know if a string is empty, but assuming by "is blank" you mean "is composed only of whitespace" then you want UnicodeStrSlice.is_whitespace(), which will be true for both empty strings and strings composed solely of characters with the White_Space unicode property set.
Only string slices implement UnicodeStrSlice, so you'll have to use .as_slice() if you're starting from a String.
tl;dr: s.is_whitespace() if s: &str, s.as_slice().is_whitespace() if s: String
Found in the doc :
impl Collection for String
fn len(&self) -> uint
fn is_empty(&self) -> bool