Acessing a field of a struct for reading
rust playpen:
use std::sync::Mutex;
#[deriving(Show)]
struct Test{
a: uint,
}
impl Test{
fn new() -> Test{
Test { a: 0}
}
fn get(&self) -> uint {
self.a
}
}
fn main() {
let t = Test{a: 42};
let m = Mutex::new(Test::new());
println!("Getting t: {} where t.a = {}", t.get(), t.a);
{
let m2 = m.lock();
println!("m2.a = {}", m2.a); // works
//println!("m2.get() = {}", m2.get()); // error: cannot borrow immutable local variable `m2` as mutable
}
}
So in this case accessing the field m2.a works, but calling m2.get() requires m2 to be mutable although get does not mutate anything and is not declared to be mutating anything especially not &self.
To make this code work I could just declare m2 with let mut m2 = m.lock(); and everything works fine, but why do I need that mut here and is there a better way to call m2.get() without declaring m2 mutable in a similar way as it works for t that I declare as non mutable and which still permits me to call t.get().
Yeah, the compiler tends to prefer to call deref_mut over deref in case both are available. In your case, deref would suffice and work, but the implicit dereferencing machinery picks deref_mut instead and then complains about m2 not being mutable.
To add to what reem said, the lock object does implement both, Deref and DerefMut and if you don't need a mutable borrow, you can get the immutable one by explicitly reborrowing it immutably:
println!("m2.get() = {}", (&*m2).get());
and if this kind of access is all you need you can also write
let m2 = m.lock();
let m2 = &*m2;
which then allows
println!("m2.get() = {}", m2.get());
This is due to a slight limitation of the Deref family of traits right now - namely implementing both Deref and DerefMut for the same type right now is slightly broken due to the behavior of autoderef for methods, namely, deref_mut is always called, even to get & references.
As a result, MutexGuard needs to be mutable for you to call methods which require &self. Usually, immutable uses of Mutex are rare, and RWLock, which supports both read and write locks separately, is better suited to this use case as it allows concurrent read locks.
Related
I want to match, e.g. an ident's type to implement a certain trait, how would I do that?
Here the basic idea in (incomplete) code:
macro_rules! has_trait {
($ ($t : ty), ($x : ident),) => {
}
}
fn trait_test() {
let a = vec![1, 2, 3];
let b = 42;
let a_iteratable = has_trait!(IntoIterator, a);
let b_iteratable = has_trait!(IntoIterator, b);
println!("{:?} iterable? {}", a, a_iteratable);
println!("{:?} iterable? {}", b, b_iteratable);
}
I cannot wrap my head around how to say "any type which has trait Foo".
I see 2 options how to tackle the problem:
Find a match expression which matches any type with trait $t and simply return true on match, else (how works else?) false.
In the body of the match of any type, use some code to determine if trait $t is implemented by the type of $x.
I cannot see how to do either of both options.
Can this even be done?
I am afraid there is here a serious misconception about what macros can and cannot do.
In Rust, a macro acts on the AST, short for Abstract Syntax Tree. This means that it has access to syntactic information (only).
It means that anything that a macro does, you can also do without a macro. A macro is just syntactic sugar to avoid writing boilerplate over and over.
And conversely, if you cannot do something without a macro, you cannot do it with a macro either.
It is not immediately clear to me whether this information is available or not (proving a negative is always so difficult), however it is certain that the usage of macros has no influence on this availability.
As the other answers have already made clear, there is nothing a macro can do. And indeed, in current (stable) Rust, that's it. However, if you are willing to either use nightly or wait until specialization is stable, you can write and implement a trait to make that distinction, e.g.
#[feature(specialization)] // nightly only for now
trait HasMyTrait {
fn has_trait() -> bool;
}
impl<T> HasMyTrait for T {
default fn has_trait() -> bool { false }
}
impl<T: MyTrait> HasMyTrait for T {
fn has_trait() -> bool { true }
}
This is just a simple example, but you can switch out multiple implementations of whatever functionality you want based on if the type in question implements a trait or not.
This code requires Rust 1.11.0 nightly as of 2016-06-02 or newer.
What you basically want is static (or compile-time) reflection:
Assigning values at compile-time, depending on the type system, to use at run-time.
This is possible in for example D or even C++, but not in Rust.
Rust does not allow template specialisation or compile-time values as generic parameters, nor does it have static reflection capabilities like D.
I have a Swift function which returns a tuple of two values. The first value is meant to usually, but not always, be used as an "updated" version of a piece of mutable state in the caller (I know I could also use inout for this instead of a tuple, but that makes it more annoying to keep the old state while preserving the new one). The second value is a generally immutable return value produced by the function, which is not intended to override any existing mutable state.
Conceptually, the usage looks like this:
var state = // initialize
(state, retval1) = process(state)
(state, retval2) = process(state)
(state, retval3) = process(state)
The problem here, obviously, is that retval1, retval2, and retval3 are never declared, and the compiler gets angry.
state must be a var and must not be redeclared, so I can't write
let (state, retval) = process(state)
However, retval is never modified and should be declared with let as a matter of best practices and good coding style.
I was hoping the following syntax might work, but it doesn't:
(state, let retval) = process(state)
How should I go about unpacking / destructuring this tuple?
I don’t believe there’s a syntax for binding with let and var simultaneously.
Interestingly, you can do it in a switch:
let pair = (1,2)
switch pair {
case (var a, let b):
++a
default:
break
}
But (var a, let b) = pair (or similar variants) don’t seem to be possible.
Does Scala have an equivelent to golangs defer?
from:
http://golang.org/doc/effective_go.html#defer
Go's defer statement schedules a function call (the deferred function) to be run immediately before the function executing the defer returns. It's an unusual but effective way to deal with situations such as resources that must be released regardless of which path a function takes to return. The canonical examples are unlocking a mutex or closing a file.
Scala does not offer defer by design, however you can create it yourself by wrapping
your function in another function, passing an object which keeps track of functions to call.
Example:
class DeferTracker() {
class LazyVal[A](val value:() => A)
private var l = List[LazyVal[Any]]()
def apply(f: => Any) = { l = new LazyVal(() => f) :: l }
def makeCalls() = l.foreach { x => x.value() }
}
def Deferrable[A](context: DeferTracker => A) = {
val dt = new DeferTracker()
val res = context(dt)
dt.makeCalls
res
}
In this example, Deferable would be the wrapping function which calls context and
returns it contents, giving it an object which tracks defer calls.
You can use this construct like this:
def dtest(x:Int) = println("dtest: " + x)
def someFunction(x:Int):Int = Deferrable { defer =>
defer(dtest(x))
println("before return")
defer(dtest(2*x))
x * 3
}
println(someFunction(3))
The output would be:
before return
dtest: 6
dtest: 3
3
I'm aware that this can be solved differently but it is really just an example that
Scala supports the concept of defer without too much fuss.
I can't think of a Scala specific way, but wouldn't this be equivalent (though not as pretty):
try {
// Do stuff
} finally {
// "defer"
}
No. Go has this construct precisely because it doesn't support exceptions and has no try...finally syntax.
Personally, I think it invites a maintenance nightmare; calls to defer can be buried anywhere in a function. Even where responsible coders put the defers right beside the thing to be cleaned up, I think it's less clear than a finally block and as for what it lets the messy coders do... at least finally blocks put all the clean-up in one place.
defer is the opposite of idiomatic Scala. Scala offers monadic ways to control program flow and defer magic does not contribute at all. Monads offer a functional improvement over try...finally which let you
Define your own error handling flow
Manipulate defined flows functionally
Make a function's anticipated errors part of its signature
defer has no place in this.
Simple problem: I am subclassing a FilterInputStream in Scala, which has a read method:
public void read(byte [] b,int offset,int len)
The data being read will be put in b, but as parameters are "vals" in Scala methods, I see no way to properly subclass this. How do I set b to the data being read? The Java *InputStream really leaves me not much choice....
You can put an item into b at index i simply by doing b(i) = whatever. That b is a val doesn't have an effect on this. It just means that you can't reassign b (which wouldn't be useful to do anyway).
Just declaring something as a val instead of a var in Scala doesn't make it immutable. In fact, var can name an immutable value. The thing to remember is that variables in Scala, much like variables in Java, are always* references, or handles, rather than actually containing the value.
Try this in your REPL:
class Container { var content: String = "default" }
val a = new Container
val b = a
b.content = "modified"
println(a.content)
When you run val b = a you are making b and a names for the same thing (not a copy, the exact same instance of Container). Because of this, when you run b.content = "modified" the change is reflected in a as well; it is just another name for the same thing. Note this happens even though a is a val. All the val means is that you can't change what instance a is a name for.
Now think about this slight variation:
class Container { var content: String = "default" }
def update(c: Container) { c.content = "modified" }
val a = new Container
update(a)
println(a.content)
When you call update, its parameter c is also a reference or alias for a. So changes are reflected outside the method call the same way they are in the earlier example.
Arrays are mutable, so they work like this as well.
*: Primitive variables (bytes, doubles, ints, etc.) are not references in Java; their boxed equivalents (java.lang.Byte...) are. It doesn't show that much since these classes/types are immutable anyway.
def read(b: Array[Byte], offset: Int, len: Int): Unit
is equivanet to following in Java:
public void read(final byte[] b, final int offset, final int len)
The array b is still mutable, and you can modify its contents.
What is the difference between a var and val definition in Scala and why does the language need both? Why would you choose a val over a var and vice versa?
As so many others have said, the object assigned to a val cannot be replaced, and the object assigned to a var can. However, said object can have its internal state modified. For example:
class A(n: Int) {
var value = n
}
class B(n: Int) {
val value = new A(n)
}
object Test {
def main(args: Array[String]) {
val x = new B(5)
x = new B(6) // Doesn't work, because I can't replace the object created on the line above with this new one.
x.value = new A(6) // Doesn't work, because I can't replace the object assigned to B.value for a new one.
x.value.value = 6 // Works, because A.value can receive a new object.
}
}
So, even though we can't change the object assigned to x, we could change the state of that object. At the root of it, however, there was a var.
Now, immutability is a good thing for many reasons. First, if an object doesn't change internal state, you don't have to worry if some other part of your code is changing it. For example:
x = new B(0)
f(x)
if (x.value.value == 0)
println("f didn't do anything to x")
else
println("f did something to x")
This becomes particularly important with multithreaded systems. In a multithreaded system, the following can happen:
x = new B(1)
f(x)
if (x.value.value == 1) {
print(x.value.value) // Can be different than 1!
}
If you use val exclusively, and only use immutable data structures (that is, avoid arrays, everything in scala.collection.mutable, etc.), you can rest assured this won't happen. That is, unless there's some code, perhaps even a framework, doing reflection tricks -- reflection can change "immutable" values, unfortunately.
That's one reason, but there is another reason for it. When you use var, you can be tempted into reusing the same var for multiple purposes. This has some problems:
It will be more difficult for people reading the code to know what is the value of a variable in a certain part of the code.
You may forget to re-initialize the variable in some code path, and end up passing wrong values downstream in the code.
Simply put, using val is safer and leads to more readable code.
We can, then, go the other direction. If val is that better, why have var at all? Well, some languages did take that route, but there are situations in which mutability improves performance, a lot.
For example, take an immutable Queue. When you either enqueue or dequeue things in it, you get a new Queue object. How then, would you go about processing all items in it?
I'll go through that with an example. Let's say you have a queue of digits, and you want to compose a number out of them. For example, if I have a queue with 2, 1, 3, in that order, I want to get back the number 213. Let's first solve it with a mutable.Queue:
def toNum(q: scala.collection.mutable.Queue[Int]) = {
var num = 0
while (!q.isEmpty) {
num *= 10
num += q.dequeue
}
num
}
This code is fast and easy to understand. Its main drawback is that the queue that is passed is modified by toNum, so you have to make a copy of it beforehand. That's the kind of object management that immutability makes you free from.
Now, let's covert it to an immutable.Queue:
def toNum(q: scala.collection.immutable.Queue[Int]) = {
def recurse(qr: scala.collection.immutable.Queue[Int], num: Int): Int = {
if (qr.isEmpty)
num
else {
val (digit, newQ) = qr.dequeue
recurse(newQ, num * 10 + digit)
}
}
recurse(q, 0)
}
Because I can't reuse some variable to keep track of my num, like in the previous example, I need to resort to recursion. In this case, it is a tail-recursion, which has pretty good performance. But that is not always the case: sometimes there is just no good (readable, simple) tail recursion solution.
Note, however, that I can rewrite that code to use an immutable.Queue and a var at the same time! For example:
def toNum(q: scala.collection.immutable.Queue[Int]) = {
var qr = q
var num = 0
while (!qr.isEmpty) {
val (digit, newQ) = qr.dequeue
num *= 10
num += digit
qr = newQ
}
num
}
This code is still efficient, does not require recursion, and you don't need to worry whether you have to make a copy of your queue or not before calling toNum. Naturally, I avoided reusing variables for other purposes, and no code outside this function sees them, so I don't need to worry about their values changing from one line to the next -- except when I explicitly do so.
Scala opted to let the programmer do that, if the programmer deemed it to be the best solution. Other languages have chosen to make such code difficult. The price Scala (and any language with widespread mutability) pays is that the compiler doesn't have as much leeway in optimizing the code as it could otherwise. Java's answer to that is optimizing the code based on the run-time profile. We could go on and on about pros and cons to each side.
Personally, I think Scala strikes the right balance, for now. It is not perfect, by far. I think both Clojure and Haskell have very interesting notions not adopted by Scala, but Scala has its own strengths as well. We'll see what comes up on the future.
val is final, that is, cannot be set. Think final in java.
In simple terms:
var = variable
val = variable + final
val means immutable and var means mutable.
Full discussion.
The difference is that a var can be re-assigned to whereas a val cannot. The mutability, or otherwise of whatever is actually assigned, is a side issue:
import collection.immutable
import collection.mutable
var m = immutable.Set("London", "Paris")
m = immutable.Set("New York") //Reassignment - I have change the "value" at m.
Whereas:
val n = immutable.Set("London", "Paris")
n = immutable.Set("New York") //Will not compile as n is a val.
And hence:
val n = mutable.Set("London", "Paris")
n = mutable.Set("New York") //Will not compile, even though the type of n is mutable.
If you are building a data structure and all of its fields are vals, then that data structure is therefore immutable, as its state cannot change.
Thinking in terms of C++,
val x: T
is analogous to constant pointer to non-constant data
T* const x;
while
var x: T
is analogous to non-constant pointer to non-constant data
T* x;
Favoring val over var increases immutability of the codebase which can facilitate its correctness, concurrency and understandability.
To understand the meaning of having a constant pointer to non-constant data consider the following Scala snippet:
val m = scala.collection.mutable.Map(1 -> "picard")
m // res0: scala.collection.mutable.Map[Int,String] = HashMap(1 -> picard)
Here the "pointer" val m is constant so we cannot re-assign it to point to something else like so
m = n // error: reassignment to val
however we can indeed change the non-constant data itself that m points to like so
m.put(2, "worf")
m // res1: scala.collection.mutable.Map[Int,String] = HashMap(1 -> picard, 2 -> worf)
"val means immutable and var means mutable."
To paraphrase, "val means value and var means variable".
A distinction that happens to be extremely important in computing (because those two concepts define the very essence of what programming is all about), and that OO has managed to blur almost completely, because in OO, the only axiom is that "everything is an object". And that as a consequence, lots of programmers these days tend not to understand/appreciate/recognize, because they have been brainwashed into "thinking the OO way" exclusively. Often leading to variable/mutable objects being used like everywhere, when value/immutable objects might/would often have been better.
val means immutable and var means mutable
you can think val as java programming language final key world or c++ language const key world。
Val means its final, cannot be reassigned
Whereas, Var can be reassigned later.
It's as simple as it name.
var means it can vary
val means invariable
Val - values are typed storage constants. Once created its value cant be re-assigned. a new value can be defined with keyword val.
eg. val x: Int = 5
Here type is optional as scala can infer it from the assigned value.
Var - variables are typed storage units which can be assigned values again as long as memory space is reserved.
eg. var x: Int = 5
Data stored in both the storage units are automatically de-allocated by JVM once these are no longer needed.
In scala values are preferred over variables due to stability these brings to the code particularly in concurrent and multithreaded code.
Though many have already answered the difference between Val and var.
But one point to notice is that val is not exactly like final keyword.
We can change the value of val using recursion but we can never change value of final. Final is more constant than Val.
def factorial(num: Int): Int = {
if(num == 0) 1
else factorial(num - 1) * num
}
Method parameters are by default val and at every call value is being changed.
In terms of javascript , it same as
val -> const
var -> var