golang two switch case strange phenomenon - switch-statement

why the second switch code can run when t value not 30, program should return in the first swtich statement, it seems wild.
following is the code:
package main
import (
"fmt"
)
func main() {
fmt.Println("start...")
// change different t value to test
t := 10
switch t {
case 10:
case 20:
case 30:
fmt.Println("30...")
return
default:
fmt.Println("d...")
return
}
fmt.Println("does the following code run ?")
switch t {
case 10:
fmt.Println("10....")
case 20:
fmt.Println("20....")
}
fmt.Println("end...")
}

Related

How does __rust_begin_short_backtrace work in Rust?

As titled.
I know that __rust_begin_short_backtrace is used for stack backtracing, but how does it work actually? I find the implementation of it is really short just like below. And what it does is only calling the passed-in function indirectly, and return back the result. I also find the counterpart function __rust_end_short_backtrace which has totally identical implementation. The code is at library/std/src/sys_common/backtrace.rs.
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in libstd are enabled, otherwise
/// it's fine to optimize away.
#[cfg_attr(feature = "backtrace", inline(never))]
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
where
F: FnOnce() -> T,
{
let result = f();
// prevent this frame from being tail-call optimised away
crate::hint::black_box(());
result
}
Another part of the related implementation is also at "library/std/src/sys_common/backtrace.rs". Below is a snippet of code of this part which I think is highly related and important, but I don't understand the logic here that how Rust deals with the symbols that relate to the previous two functions:
backtrace_rs::trace_unsynchronized(|frame| {
if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
return false;
}
let mut hit = false;
let mut stop = false;
backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
hit = true;
if print_fmt == PrintFmt::Short {
if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
if sym.contains("__rust_begin_short_backtrace") {
stop = true;
return;
}
if sym.contains("__rust_end_short_backtrace") {
start = true;
return;
}
}
}
if start {
res = bt_fmt.frame().symbol(frame, symbol);
}
});
if stop {
return false;
}
if !hit {
if start {
res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
}
}
idx += 1;
res.is_ok()
});
Rust is inserting these "dummy symbols" to allow a short backtrace.
Consider this code
fn a() {
b()
}
fn b() {
c()
}
fn c() {
d()
}
fn d() {
panic!()
}
fn main() {
a()
}
This gives a nice backtrace
$ rustc demo.rs
$ RUST_BACKTRACE=1 ./demo
thread 'main' panicked at 'explicit panic', demo.rs:14:5
stack backtrace:
0: std::panicking::begin_panic
1: demo::d
2: demo::c
3: demo::b
4: demo::a
5: demo::main
6: core::ops::function::FnOnce::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
If we instead use RUST_BACKTRACE=full
$ RUST_BACKTRACE=full ./demo
thread 'main' panicked at 'explicit panic', demo.rs:14:5
stack backtrace:
0: 0x107e34fe4 - std::backtrace_rs::backtrace::libunwind::trace::ha70d3c0580051b5e
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
1: 0x107e34fe4 - std::backtrace_rs::backtrace::trace_unsynchronized::h70c3b3ef22cddd13
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x107e34fe4 - std::sys_common::backtrace::_print_fmt::h698e42c1766250fa
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/sys_common/backtrace.rs:67:5
3: 0x107e34fe4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h18cc31b07c2f1a67
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/sys_common/backtrace.rs:46:22
4: 0x107e4808d - core::fmt::write::h24f8349e8e89c9af
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/core/src/fmt/mod.rs:1096:17
5: 0x107e33046 - std::io::Write::write_fmt::hc54d7d6e95b15753
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/io/mod.rs:1568:15
6: 0x107e36b79 - std::sys_common::backtrace::_print::h07ca439149358748
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/sys_common/backtrace.rs:49:5
7: 0x107e36b79 - std::sys_common::backtrace::print::hb7331bf9c4b208ca
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/sys_common/backtrace.rs:36:9
8: 0x107e36b79 - std::panicking::default_hook::{{closure}}::h11b550d560f5cc66
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:208:50
9: 0x107e36709 - std::panicking::default_hook::he168e99d1cf91c3c
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:225:9
10: 0x107e371fb - std::panicking::rust_panic_with_hook::hf87bfc4afef21ea6
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:591:17
11: 0x107e18d27 - std::panicking::begin_panic::{{closure}}::h631923d2be23e79e
12: 0x107e18998 - std::sys_common::backtrace::__rust_end_short_backtrace::h891b6a0b6f9c1b80
13: 0x107e4bcfb - std::panicking::begin_panic::hd2dfddb0fed650c0
14: 0x107e18aec - demo::d::h9d9ff8ddd5377da5
15: 0x107e18ac9 - demo::c::haceeec3fee4323ba
16: 0x107e18ab9 - demo::b::h4146166847508fc7
17: 0x107e18aa9 - demo::a::h60d47e17615f49c4
18: 0x107e18af9 - demo::main::h60dea0663d4b849d
19: 0x107e18bea - core::ops::function::FnOnce::call_once::hf435db03deecd456
20: 0x107e189cd - std::sys_common::backtrace::__rust_begin_short_backtrace::h936624db758e7870
21: 0x107e194d0 - std::rt::lang_start::{{closure}}::ha060b13a4d59d3f5
22: 0x107e37574 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h0e377e204feaadc3
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/core/src/ops/function.rs:259:13
23: 0x107e37574 - std::panicking::try::do_call::h9c5b8eda90bbe0b7
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:379:40
24: 0x107e37574 - std::panicking::try::he150bdff9d5b30f2
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:343:19
25: 0x107e37574 - std::panic::catch_unwind::h04e9c415c0907892
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panic.rs:431:14
26: 0x107e37574 - std::rt::lang_start_internal::h86f505dc7de50d93
at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/rt.rs:51:25
27: 0x107e194a5 - std::rt::lang_start::h9d080ccd85b4c518
28: 0x107e18b22 - _main
Which is the full stack trace. However is isn't very usefull as most of it is language internals. Therefor, in the normal mode, rust scans the stack for the __rust_end_short_backtrace and __rust_begin_short_backtrace functions.
These functions dont do anything (hence the trickery to stop them being optimized away), but are rust their for the backtracer to pick up.

I've started a panic with my index out of range, and I can't get out [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
I'm writing this program to become comfortable with types (not objects!).
The basic premise is the user enters an animal name (cow, snake bird), then an action (eat, move, sound.) My code then looks it up and returns the value.
So, the user entry is suppose to be on ONE line separated by a " ". I use strings.Split.
I'm getting a "panic" notice when the user only enters a single char. I'm thinking this panic arises out of the compiler trying to "split" a single char.
TWO Questions:
1. Am I right?
2. How do I fix it?
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
//Create our type object.
type animal struct {
aType, eats, moves, sounds string
}
//Create our methods.
func (animal animal) info (querie string) {
if querie == "eats" {
fmt.Printf("The animal, %s , eats %s\n ", animal.aType, animal.eats)
} else if querie == "moves" {
fmt.Printf("The animal, %s , moves by %s\n ", animal.aType, animal.moves)
} else {
fmt.Printf("The animal, %s , makes the sound %s\n ", animal.aType, animal.sounds)
}
}
func main() {
//Now create our animals
cow := animal{aType:"cow", eats: "grass", moves: "walking", sounds: "moo"}
bird := animal{aType:"bird", eats: "worms", moves: "flying", sounds: "peep"}
snake := animal{aType:"snake", eats: "mice", moves: "slithering", sounds: "hiss"}
// need a boolean to perpetuate our loop
var flag bool = true
for flag {
fmt.Println("Remember enter X to exit")
fmt.Printf(">please enter your (format: type & information) request -> ")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
request := scanner.Text()
//Capture user entered data
typed := strings.Split(request, " ")[0]
if typed == "X" {
flag = false
break
}
infoe := strings.Split(request, " ")[1]
// contruct the logic tree.
if !((infoe == "eat") || (infoe == "move") || (infoe == "speak")) {
switch typed {
case "cow":
cow.info(infoe)
case "snake":
snake.info(infoe)
case "bird":
bird.info(infoe)
default:
fmt.Println("I don't know about that animal.")
}
} else {
fmt.Printf("I don't have that informtion")
break
}
}
}
Create the scanner outside the loop to avoid discarding buffered data. Break when Scan() returns false. Check for and handle invalid input.
scanner := bufio.NewScanner(os.Stdin)
for {
fmt.Println("Remember enter X to exit")
if !scanner.Scan() {
break
}
request := scanner.Text()
parts := strings.Split(request, " ")
if parts[0] == "X" {
break
}
if len(parts) < 2 {
fmt.Println("bad input")
break
}
typed := parts[0]
infoe := parts[1]
...
To simplify your code, I would suggest using fmt.Scanf as shown below:
package main
import "fmt"
func main() {
var animal, action string
fmt.Printf("Enter animal: ")
fmt.Scanf("%s", &animal)
fmt.Printf("Enter action: ")
fmt.Scanf("%s", &action)
fmt.Printf("Animal was %s and action was %s", animal, action)
}
Also am not sure why there are multiple downvotes. Is it the problem with the way the code is written? I think that's ok if someone is just trying to learn the language. First get it working and then focus on other things.
Once you are comfortable with the language, you can go through points listed in Effective Go

Where can I find documentation for the types of knex errors?

I've scoured the internet but it seems that I can't find documentation for the different types of Knex errors.
I would like to know these so I can implement proper error handling for my project. Where can I find this? They briefly mention the query error object here but no further depth is given. Am I missing something? It seems basic to me that they should have this well-documented.
What #Mikael said. It's a passthrough. For SQLite there are lists of DB errors here and here.
The db error code is included on the thrown exception object as the attribute .errno. I use this and the db driver documentation to be more verbose about the errors with the following function:
/**
* Gets Error strings using DB driver error number
* #param {number} errNo Database error number
* returns {object} errs: {"int":"Internal use string", "ext":"External usage string"};
*/
function getDBError(errNo) {
if (!errNo) {errNo = 0; };
let errs = {"int":null, "ext":null};
switch(errNo) {
case 2: errs.int="Internal logic error in SQLite"; break;
case 3: errs.int="Access permission denied"; break;
case 4: errs.int="Callback routine requested an abort"; break;
case 5: errs.int="The database file is locked"; break;
case 6: errs.int="A table in the database is locked"; break;
case 7: errs.int="A malloc() failed"; break;
case 8: errs.int="Attempt to write a readonly database"; break;
case 9: errs.int="Operation terminated by sqlite3_interrupt()"; break;
case 10: errs.int="Some kind of disk I/O error occurred"; break;
case 11: errs.int="The database disk image is malformed"; break;
case 12: errs.int="Unknown opcode in sqlite3_file_control()"; break;
case 13: errs.int="Insertion failed because database is full"; break;
case 14: errs.int="Unable to open the database file"; break;
case 15: errs.int="Database lock protocol error"; break;
case 16: errs.int="Database is empty"; break;
case 17: errs.int="The database schema changed"; break;
case 18: errs.int="String or BLOB exceeds size limit"; break;
case 19: errs.int="Abort due to constraint violation"; break;
case 20: errs.int="Data type mismatch"; break;
case 21: errs.int="Library used incorrectly"; break;
case 22: errs.int="Uses OS features not supported on host"; break;
case 23: errs.int="Authorization denied"; break;
case 24: errs.int="Auxiliary database format error"; break;
case 25: errs.int="2nd parameter to sqlite3_bind out of range"; break;
case 26: errs.int="File opened that is not a database file"; break;
case 27: errs.int="Notifications from sqlite3_log()"; break;
case 28: errs.int="Warnings from sqlite3_log()"; break;
case 100: errs.int="sqlite3_step() has another row ready"; break;
case 101: errs.int="sqlite3_step() has finished executing"; break;
case 301: errs.int="no such column"; break;
case 302: errs.int="no such table"; break;
case 303: errs.int="Cannot start a transaction within a transaction"; break;
default: errs.int="Database processing Error #"+errNo; break;
}
// errs.ext is future use to include end user messages and is currently ignored
if (!errs.ext) {errs.ext = errs.int; };
return errs;
};
There is no documentation of different errors thrown by knex. There are not that many places where knex actually creates Errors, usually its some other package where error is originated, except for some validations that feature is supported by the selected driver.
If a query fails, knex just passes the original error that was thrown by the database driver.

XPages create a full text index in SSJS

I have a DB that must be full text indexed, so I added the code below to create one if it is not allready indexed:
if (database.isFTIndexed()){
database.updateFTIndex(false)
} else {
var options:int = database.FTINDEX_ALL_BREAKS + database.FTINDEX_ATTACHED_FILES + database.FTINDEX_IMMEDIATE
database.createFTIndex(options , true);
database.updateFTIndex(false);
}
sessionScope.put("ssSelectedView","vwWFSProfile")
When it runs I get the following error:
Error source
Page Name:/xpWFSAdmin.xsp
Control Id: button2
Property: onclick
Exception
Error while executing JavaScript action expression
com.ibm.jscript.types.GeneratedWrapperObject$StaticField incompatible with com.ibm.jscript.types.FBSValue
Expression
1: #{javascript:if (database.isFTIndexed()){
2: database.updateFTIndex(false)
3: } else {
4: var options:int = database.FTINDEX_ALL_BREAKS + database.FTINDEX_ATTACHED_FILES + database.FTINDEX_IMMEDIATE
5: database.createFTIndex(options , true);
6: database.updateFTIndex(false);
7: }
8: sessionScope.put("ssSelectedView","vwWFSProfile")}
It is choking on line 4 it does not like the summing of the parameters. So I comment out line 4 and change line 5 to read database.createFTIndex(4, true)
then I get this error:
Error while executing JavaScript action expression
Script interpreter error, line=5, col=18: [TypeError] Exception occurred calling method NotesDatabase.createFTIndex(number, boolean) null
JavaScript code
1: if (database.isFTIndexed()){
2: database.updateFTIndex(false)
3: } else {
4: //var options:int = database.FTINDEX_ALL_BREAKS + database.FTINDEX_ATTACHED_FILES + database.FTINDEX_IMMEDIATE
5: database.createFTIndex(4 , true);
6: database.updateFTIndex(false);
7: }
8: sessionScope.put("ssSelectedView","vwWFSProfile")
Can't seem to get it to work. I can go into the DB and manually create the index so it is not a rights issue.
As far as I can read from the help, you can not use database.FTINDEX_IMMEDIATE as parameter for createFTIndex() only for setFTIndexFrequency().
So remove the use of database.FTINDEX_IMMEDIATE and do this:
var options:int = database.FTINDEX_ALL_BREAKS + database.FTINDEX_ATTACHED_FILES;
database.createFTIndex(options , true);
You can then call setFTIndexFrequency() like this:
database.setFTIndexFrequency(database.FTINDEX_IMMEDIATE);

Switch case confusion

I came across this problem and was confused when I got the answer wrong
String s = "dog";
switch( s )
{
case "dag" : System.out.print("7");
case "dog" : System.out.print("8");
case "dug" : System.out.print("9");
}
The answer comes out to 89 but I'm not sure why. I thought it was just 8. Thanks in advance for any help.
It happens because you don't break; after you've found a match, so it will continue to fall through. It's done in such a way so you can catch multiple things at once:
case 1:
case 2:
case 3:
// do something for 1-3
break;
With your code, you'd need
switch (s) {
case "dag":
System.out.print("7");
break;
case "dog":
System.out.print("8");
break;
case "dug":
System.out.print("9");
break;
}
You forgot to use break.
case "dog": //print
break;

Resources