I have a very simple project. It is Command Line Tool written on Swift 3.0 using Xcode 8.0. This program is:
import Foundation
func aaa() {
print(a)
}
let a = "a"
aaa()
This is working perfectly well and printing "a" in console, but lets do this program more complex:
import Foundation
func aaa() {
print(a)
print(b)
}
let a = "a"
let b = "b"
aaa()
And line
print(b)
is marked with error
Use of unresolved identifier 'b'
We can make even easier:
import Foundation
func aaa() {
print(a)
}
aaa()
let a = "a"
And again, line
print(a)
is marked with error
Use of unresolved identifier 'a'
I am not newbie and I undertand that I can easily fix this error like putting all variables in the beginning of the program. Question is: why is it happening?
I thought each file with extension .swift, it is a class and I can put variable and functions, call functions in any order (all variables and constants would be global)... And one last thing, I don't have ability to test this on Swift 2.2, but I don't remember I faced this bug before, so can it be a error of Swift 3.0 compiler?
Thank you for any answer!
It appears to be a Swift compiler error:
When I tested it with other variables:
It always skips first issue and complies at second variable, at first.
Generally, if wanted to access a variable, that's inside a function, and wanted to do any action with such a variable, it must be declared there.
I would follow this convention everywhere.
Related
hmm...
I imported:System.math...
test as integer=sgn(100)
I get the error: sgn is not declared.
Other math functions work.
So Why?
Might Visual Studio not be correctly installed?
Thank Yall!
flabbergasted: Jhonny Q
Missing the character "i"
That particular Math function is named sign.
Thus sgn, being user defined, misses its declaration.
Thanks for you response; Sep Roland.
That alone still gets me a: is not declared.
What works is: Math.Sign. ,or do a: Imports System.Math.
Then sign works also.
A snip of Rust code:
pub fn main() {
let a = "hello";
let b = a.len();
let c =b;
println!("len:{}",c)
}
When debugging in CLion, Is it possible to evaluate a function? For example, debug the code step by step, now the code is running to the last line println!... and the current step stops here, by adding the expression a.len() to the watch a variable window, the IDE can't evaluate the a.len(). It says: error: no field named len
This is the same reason you can't make conditional breakpoints for Rust code:
Can't create a conditional breakpoint in VSCode-LLDB with Rust
I hope, I'm not too late to answer this, but with both lldb and gdb, Rust debugging capability is currently rather constrained.
Expressions that are straightforward work; anything complex is likely to produce issues.
My observations from rust-lldb trying this, are that only a small portion of Rust is understood by the expression parser.
There is no support for macros.
Non-used functions are not included in the final binary.
For instance, since that method is not included in the binary, you are unable to execute capacity() on the HashMap in the debugger.
Methods must be named as follows:
struct value.method(&struct value)
There is no technique that I've discovered to call monomorphized functions on generic structs (like HashMap).
For example, "hello" is a const char [5] including the trailing NUL byte. String constants "..." in lldb expressions are produced as C-style string constants.
Therefore, they are not valid functions
While Coding in Python, I often do something like
test.py
x = []
breakpoint()
± |master U:5 ?:4 ✗| → python3 test.py
-> breakpoint()
(Pdb) x
[]
(Pdb) x.append(1)
(Pdb) x
[1]
Is it possible to execute the statement while debugging Rust?
use std::collections::HashMap;
fn main() {
let mut contacts = HashMap::new();
contacts.insert("Daniel", "798-1364");
contacts.insert("Ashley", "645-7689");
//set breakpoint here
}
So far, I can execute p contacts in the debug console, the meaning of this output isn't straight to me. What if I want to know the outcome of println!("{:?}", contacts); without writting this line of code in the source file.
And also I want to know the outcome of contacts.insert("Robert", "956-1742"), If I execute expr contacts.insert("Robert", "956-1742") in the debug console, it says error: no field named insert.
Rust debugging support is currently quite limited with both lldb and gdb. Simple expressions work, anything more complex is likely to cause problems.
My experience while testing this with rust-lldb:
The expression parser only understands a limited subset of Rust. Macros are not supported.
Functions that are not used are not included in the resulting binary. E.g. you cannot call capacity() on the HashMap in the debugger since that function is not included in the binary.
Methods have to be called like this: struct_value.method(&struct_value)
I haven't found a way to call monomorphized methods on generic structs (like HashMap).
String constants "..." in lldb expressions are created as C-style string constants, e.g. "abcdef" is a const char [7] including the trailing NUL byte. Thus they cannot be easily passed to Rust functions expecting &str arguments.
Trying to use a helper function like this:
pub fn print_contacts(contacts: &HashMap<&str, &str>) {
println!("{:?}", contacts);
}
causes lldb to crash:
(lldb) expr print_contacts(&contacts)
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0. Program arguments: [...]
Segmentation fault: 11
So it seems that what you want to do is not possible at this time.
Now I'm really confused. Here is my problem (Go is new to me):
Firs file:
// main.go
package main
import "./libraries/test"
func main() {
test.foo()
}
Second file:
// test.go
package test
import "fmt"
func foo() {
fmt.Println("foo")
}
My structure looks like this:
main.go
/libraries
/test
test.go
If I compile this code I'll get this error messages:
./main.go:7: cannot refer to unexported name test.foo
./main.go:7: undefined: test.foo
If I change foo to Foo everywhere the error is gone and the program works as expected.
In Go, it's an important distinction whether a symbol's name is written in upper or lower camel case. This goes for functions, but also for types (like structs or interfaces) and also struct members.
You can read this up in the Go documentation (emphasis mine):
Names are as important in Go as in any other language. They even have semantic effect: the visibility of a name outside a package is determined by whether its first character is upper case.
This means that you cannot name functions and types arbitrarily. If you need to call this function from another module, it must be named Foo, and not foo.
I suppose that you have not read the Go docs very closely. All names which begin with capital letters are exported from their package. All names in lowercase are not exported.
https://golang.org/doc/
https://golang.org/ref/spec#Exported_identifiers
I've been writing a test program to assist in learning Go. While doing so, I've encountered a few instances where I thought the compiler should have detected an error. I've encountered another similar situation, so I thought I should ask why this situation is not treated as an error.
Example situation :
if oError = rwfile.WriteLines(asParams, sParamsFilename); oError != nil {
fmt.Printf("Error on write to file Params. Error = %s\n", oError)
} else {
println("Params file write OK")
}
In the example above, whether or not the variable "oError" is declared, the compiler does not indicate an error. It also works if the line contains the following when the variable is not declared (as expected):
if oError := rwfile.WriteLines(asParams, sParamsFilename); oError != nil {
If I declare the variable "oError", then ":=" does not work (as expected).
"rwfile" is a package that I have written, and the function in question starts as follows:
func WriteLines(asBuff []string, sFilename string) error { // write text file
If I create an error with the write of the file, and use "=" without declaring the variable "oError", the program works correctly and detects the non-nil "oError" variable.
So, why is use of "=" in the above not treated as an error when oError is not declared a variable?
The Go version is go1.1.2 Windows/386.
This means that you have an variable named oError elsewhere in the package. (Note that this variable need not be in the same file; it could be in a different file with the same package clause.) So, when you use oError = ..., you're assigning a value to that package variable, and when you use oError := ..., you're declaring a local variable that hides the package variable. (Per the specification, "An identifier declared in a block may be redeclared in an inner block. While the identifier of the inner declaration is in scope, it denotes the entity declared by the inner declaration." [link])
If you try a different identifier, a unique one, you should see that the compiler indeed complains.
It's unrelated to the actual question, but `go fmt` can really help with tracking errant stuff in a big program.
Also, following the style guidelines really helps: use terse code styles (no hungarian variable names! took me ages to get used to short names) and short files: a 2Kloc file is probably too big. It's massively worth taking a wander through the standard library source code to see what good Go code looks like