I have copy pasted some code from a tutorial but when I arrived here:
azimuth = Math.round(azimuth.toFloat())
compass_image.rotation = (-azimuth).toFloat()
val where = when(azimuth){
in 281...348 -> "NW"
in 281...348 -> "NW"
in 281...348 -> "NW"
in 281...348 -> "NW"
in 281...348 -> "NW"
in 281...348 -> "NW"
in 281...348 -> "NW"
else -> "N"
}
view_degree.text = "$azimuth° $where"
Android Studio failed to recognize the command "in"... How come?
Thanks in advance
It's because you have to use two dots instead of three to express ranges. Furthermore, all those cases are equal so it's useless to repeat them.
val where = when(azimuth){
in 281..348 -> "NW"
else -> "N"
}
Additional info here: kotlinlang.org/docs/reference/ranges.html
Related
I'm trying to plot to graphs in one canvas using Cern ROOT. When I use gr -> Draw("ap") and gr2 -> Draw("p1 same"), the lines of the plots are not visible, only the markers are visible. When I use gr1 -> Draw("") and gr2 -> Draw("same"), the first plot is visible with line and marker but the second plot is only visible with line and not markers.
I want to see both of their lines and markers. How can I do it? My code:
graph_one -> GetXaxis() -> SetTitle(" x ");
graph_one -> GetYaxis() -> SetTitle(" y ");
graph_one -> GetXaxis() -> SetRangeUser(0,8);
graph_one -> GetYaxis() -> SetRangeUser (0,3);
graph_one -> SetLineWidth(2);
graph_one -> SetLineColor(kBlack);
graph_one -> SetMarkerStyle(8);
graph_one -> SetMarkerSize(3);
graph_one -> SetMarkerColor(kRed);
graph_two -> SetLineWidth(2);
graph_two -> SetMarkerStyle(8);
graph_two -> SetMarkerSize(3);
graph_two -> SetLineColor(kBlue);
graph_two -> SetMarkerColor(kBlack);
graph_one -> Draw("");
graph_two -> Draw("same");
Use
graph_one -> Draw("acp");
graph_two -> Draw("cp");
a draws the axes around the graph (obviously needed only for one graph)
c draws a continuous line between the markers
p draws the markers themselves
(this is explained in https://root.cern.ch/doc/master/classTGraphPainter.html#GrP1)
Please note there is no same drawing option for TGraph.
Lets assume the following when-statement:
when(a)
{
x -> doNothing()
y -> doSomething()
else -> doSomethingElse()
}
Now i'm looking to eliminate the boilerplate-function "doNothing()", e.g.:
x -> //doesn't compile
x -> null //Android Studio warning: Expression is unused
x -> {} //does work, but my corporate codestyle places each '{‘ in a new line, looking terrible
//also, what is this actually doing?
Any better ideas?
I can't just eliminate x -> completely, as that would lead to else -> doSthElse()
Edit: directly after writing this Question, i figured out a possible answer x -> Unit. Any shortcomings with that?
Kotlin has two existing possibilities to express a "do nothing" construct in when statements. Either Unit or an empty pair of braces. An empty block will just execute nothing.
There's nothing else planned in that regard (see here).
To answer your question regarding "also, what is this actually doing?" for the empty block, looking at the bytecode and translating it into Java helps:
val x = 33
when(x)
{
1 -> {}
2 -> Int
3 -> Unit
else -> Double
}
Translates to
int x = 33;
switch(x) {
case 1:
case 3:
break;
case 2:
IntCompanionObject var10000 = IntCompanionObject.INSTANCE;
break;
default:
DoubleCompanionObject var1 = DoubleCompanionObject.INSTANCE;
}
I have some code that roughly looks like this:
val myObject = myObjectRepository.findById(myObjectId);
when {
matchesSomething(myObject) -> doSomethingWithMyObject(myObject)
matchesSomethingElse(myObject) -> doSomethingElseWithMyObject(myObject)
else -> log.warn("No match, aborting");
}
While this works I would think that the following (which doesn't work) would be an improvement if I only need access to myObject inside the scope of when:
when(myObjectRepository.findById(myObjectId)) { myObject ->
matchesSomething(myObject) -> doSomethingWithMyObject(myObject)
matchesSomethingElse(myObject) -> doSomethingElseWithMyObject(myObject)
else -> log.warn("No match, aborting");
}
The error I get here is:
Unresolved reference: myObject
Can you do something like this in Kotlin and if so how? If not, is there a particular reason for why this shouldn't be allowed?
As shown in the documentation, the proper syntax would be
val myObject = myObjectRepository.findById(myObjectId);
when {
matchesSomething(myObject) -> doSomethingWithMyObject(myObject)
matchesSomethingElse(myObject) -> doSomethingElseWithMyObject(myObject)
else -> log.warn("myObject not found, aborting")
}
Or, to actually match what your first snippet does:
val myObject = myObjectRepository.findById(myObjectId);
when(myObject) {
null -> log.warn("myObject not found, aborting");
matchesSomething(myObject) -> doSomethingWithMyObject(myObject)
matchesSomethingElse(myObject) -> doSomethingElseWithMyObject(myObject)
}
You have to be careful about the syntax. In a while we use an arrow -> which has nothing to do with lambdas. I think this is what you were trying in your example.
The only valid syntax for when is this:
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // Note the block
print("x is neither 1 nor 2")
}
On the left side of the arrow -> you declare what the object (x) is being matched against, whereas on the right side you tell what will be executed in that case. Read about this here.
In your example you tried to chain multiple -> which does not work.
This is supported as of Kotlin 1.3. It's referred to as "Capturing when subject in a variable" and looks like this (taken from their documentation):
fun Request.getBody() =
when (val response = executeRequest()) {
is Success -> response.body
is HttpError -> throw HttpException(response.status)
}
If I log a function:
Debug.log "List.foldl" (toString List.foldl)
<function> : a -> a
I get its function signature. How do I get the body of the function?
Debug.log takes two arguments: string and any variable. Both of them will be printed out and first paramenter should be used as a simple description what you are sending to logs.
In your case it could be:
Debug.log "List.foldl func" <| List.foldl
<function>
: (a -> b -> b) -> b -> List a -> b
Is it possible to see the interface of a loaded module in interactive OCaml? I have (unsuccessfully) tried searching for such a possibility, and online docs/sources are not what I am looking for.
The standard trick for this is to define a synonym for the module, which induces the toplevel to list the interface.
$ ocaml
OCaml version 4.00.1
# #load "str.cma";;
# module S = Str;;
module S :
sig
type regexp = Str.regexp
val regexp : string -> regexp
val regexp_case_fold : string -> regexp
val quote : string -> string
val regexp_string : string -> regexp
val regexp_string_case_fold : string -> regexp
val string_match : regexp -> string -> int -> bool
. . .
val first_chars : string -> int -> string
val last_chars : string -> int -> string
end
Update
(Note that this answer is from 2013. Recent revisions of OCaml provide a toplevel directive to show a module interface:
# #show_module Str;;
module Str :
sig
type regexp
val regexp : string -> regexp
. . .
val first_chars : string -> int -> string
val last_chars : string -> int -> string
end
So the semi-clever workaround is no longer required.
(There are many new directives. Type #help;; at toplevel to get a list.)
Both utop and ocaml interpreters added the #show directive since a moment. It does exactly what you want, as in the following example :
│ Welcome to utop version 1.19.3 (using OCaml version 4.04.0) │
└──────────────────────────────────────────────────────────────┘
Type #utop_help for help about using utop.
─( 15:12:33 )─< command 0 >──────────────────────────────────────{ counter: 0 }─
utop # #show List;;
module List :
sig
val length : 'a list -> int
val cons : 'a -> 'a list -> 'a list
val hd : 'a list -> 'a
...
val fast_sort : ('a -> 'a -> int) -> 'a list -> 'a list
val sort_uniq : ('a -> 'a -> int) -> 'a list -> 'a list
val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
end
PS:i'm using 4.04 version but i know that it also works for 4.03.> and maybe before that too.
In OCaml toplevel version 4.04.0, the trick of defining a module's synonym works no more:
# module L = List;;
module L = List
#
but you can use the include directive:
# module L = struct include List end;;
module L :
sig
val length : 'a list -> int
val cons : 'a -> 'a list -> 'a list
val hd : 'a list -> 'a
val tl : 'a list -> 'a list
val nth : 'a list -> int -> 'a
val rev : 'a list -> 'a list
...
val sort_uniq : ('a -> 'a -> int) -> 'a list -> 'a list
val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
end
#