#Why doesn't this work?
47 messages · Page 1 of 1 (latest)
bannedList is a local variable
it will always be set to []string when the function is run
you need a struct to hold the list of banned ip
func main() {
Hello("hello")
Hello("world")
Hello("1")
Hello("2")
Hello("3")
}
func Hello(s string) {
store := ""
store += s
fmt.Println(store)
}
```will result in
hello
world
1
2
3
if a global variable is used
hello
helloworld
helloworld1
helloworld12
helloworld123
```https://goplay.tools/snippet/lgJ_foMe25L
using struct will make more sense but this is an example
wait
If i append a struct
idk
Can i just use the array but like
make it global scoped
you could but that's generally bad idea
imo globals generally should be avoided unless there's no other approach
another example using a struct https://goplay.tools/snippet/upv2z-oUmrG
Better Go Playground with syntax highlight support
Yeah bot how could I add to it automatically lol
the recommended way would be to use strings.Builder
func main() {
sb := new(strings.Builder)
sb.WriteString("hello")
fmt.Println(sb.String())
sb.WriteString("world")
fmt.Println(sb.String())
sb.WriteString("1")
fmt.Println(sb.String())
sb.WriteString("2")
fmt.Println(sb.String())
sb.WriteString("3")
fmt.Println(sb.String())
}
this will return
hello
helloworld
helloworld1
helloworld12
helloworld123
mine is just an example, see the original post for context as to why i did what i did
i am using string as a simplification instead of using slice
my function prints it out, but it's also added into the string
yours would return true or false, and adds it into the slice
which part do you have problem here
so he aims to only print once from an ip before permanently banned?
my print is just a demonstration to show how no data gets stored
they want to return bool if the ip has been used before
cool, probably storing it to a map would be simpler as you could easily delete entries too
No, I'm trying to make it so you can only post a request from one ip and then it'll reject it
You could use the https://github.com/matryer/resync package. Create a map of type map[string]resync.Once then call the Once for each ip. No matter how many times you call it, it would only run once
you cant store it into disk, but you could store []string or map[string]bool into disk
@rotund plume if it's not in the banned ip list, why are you adding it, instead of returning false? Based on the name of the function it should not do anything other than returning true or false.
To make it only one use?
@rotund plume what I mean is the name of the function doesn't completely describe what it does. checkIfBanned means it should return true or false indicating whether the ip address is banned. If you want to add the ip address to the banned list if it isn't already banned, then renaming the function or better writing another function is better.
E.g. something like this:
if checkIfBanned(ipaddress) {
bannedList = append(bannedList, ipaddress)
}
}
You know your code better than I do so the above might need modifying to fit nicely within your codebase
you should bind to a struct called banlist instead, see this example
you could have a banip and a checkbanned function from a banlist struct
yeah but how can i append that struct
you append to a field inside the struct instead of appending to the struct
https://goplay.tools/snippet/BitK_QgCsqg (edited to also add a "Has" check method)
Seems pretty complicated..
it's better then storing using globals or passing slices
@solemn talon I think telling op why A is better than B would be a more convincing reason to switch to A.
good point thanks for the feedback:
certainly using a single global state would be the least complex operation here
you could just call AddToBannedList and IsInBannedList from anywhere and it would just work
but easiest is not always the best solution, now what if you want 2 list for 2 different things? using global variables is a non modular approach
using a struct would allow you to have multiple structs which each will have it's own state
global state also makes it hard to evaluate code flow, instead of seeing something clearly passed from one function to another, a global variable is accessible form anywhere, which may sound useful but it makes it so you cant clearly tell where things originates from
the benefits of having a struct with methods means, it's not going to change out of now here, you need to explicitly pass it from one place to another
it also incentive proper structuring and passing of data, rather then relying on being available from anywhere
you can also have multiples of it, instead of being locked into only one, because states is not coupled with global variable
do you really need it? absolutely not, your program will work just fine either way
it's not going cause your program to crash and burn, just annoying to refactor out at in the future
The problem is that I'm extremely new to go and i find stuff weird
you can think of it as syntactic sugar to always automatically pass a certain set of data basically
see example without struct https://goplay.tools/snippet/BitK_QgCsqg
func main() {
store := []string{}
Add(store, "foo")
Add(store, "bar")
Add(store, "baz")
fmt.Printf("has baz %v\n", Has(store, "baz"))
fmt.Printf("has foobar %v\n", Has(store, "foobar"))
}
```The difference
```go
func main() {
s := &Storer{}
s.Add("foo")
s.Add("bar")
s.Add("baz")
fmt.Printf("has baz %v\n", s.Has("baz"))
fmt.Printf("has foobar %v\n", s.Has("foobar"))
}
it's fundamentally doing the same thing here, one is just nicer to use
otherwise it's all just sugar
(in this case passing 1 slice isnt that much, but when a function needs multiple data states, it will get out of hand)